xref: /aosp_15_r20/external/cronet/base/win/access_control_list_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/win/access_control_list.h"
6 
7 // clang-format off
8 #include <windows.h>  // Must be in front of other Windows header files.
9 // clang-format on
10 
11 #include <sddl.h>
12 
13 #include <string>
14 #include <vector>
15 
16 #include "base/check.h"
17 #include "base/strings/string_number_conversions_win.h"
18 #include "base/win/scoped_localalloc.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 namespace base::win {
22 
23 namespace {
24 
25 constexpr wchar_t kFromPACLTest[] = L"(D;;FX;;;SY)(A;;GA;;;WD)";
26 constexpr wchar_t kNullAcl[] = L"NO_ACCESS_CONTROL";
27 constexpr wchar_t kEvent[] = L"(A;;0x1f0003;;;WD)";
28 constexpr wchar_t kEventWithSystemInherit[] =
29     L"(D;OICI;DC;;;SY)(A;;0x1f0003;;;WD)";
30 constexpr wchar_t kEventSystemOnlyInherit[] = L"(D;OICI;DC;;;SY)";
31 constexpr wchar_t kEventReadControl[] = L"(A;;RC;;;WD)";
32 constexpr wchar_t kEventReadControlModify[] = L"(A;;DCRC;;;WD)";
33 constexpr wchar_t kUntrustedLabel[] = L"(ML;;;;;S-1-16-0)";
34 constexpr wchar_t kSystemLabel[] = L"(ML;;;;;SI)";
35 constexpr wchar_t kSystemLabelInherit[] = L"(ML;OICI;;;;SI)";
36 constexpr wchar_t kSystemLabelPolicy[] = L"(ML;;NWNRNX;;;SI)";
37 constexpr wchar_t kSystemLabelInheritPolicy[] = L"(ML;OICI;NWNRNX;;;SI)";
38 constexpr wchar_t kDaclPrefix[] = L"D:";
39 constexpr wchar_t kSaclPrefix[] = L"S:";
40 
ConvertSddlToAcl(const wchar_t * sddl)41 std::vector<char> ConvertSddlToAcl(const wchar_t* sddl) {
42   std::wstring sddl_dacl = kDaclPrefix;
43   sddl_dacl += sddl;
44   PSECURITY_DESCRIPTOR sd = nullptr;
45   CHECK(::ConvertStringSecurityDescriptorToSecurityDescriptor(
46       sddl_dacl.c_str(), SDDL_REVISION_1, &sd, nullptr));
47   auto sd_ptr = TakeLocalAlloc(sd);
48   CHECK(sd_ptr);
49   BOOL present = FALSE;
50   BOOL defaulted = FALSE;
51   PACL dacl = nullptr;
52   CHECK(::GetSecurityDescriptorDacl(sd_ptr.get(), &present, &dacl, &defaulted));
53   CHECK(present);
54   char* dacl_ptr = reinterpret_cast<char*>(dacl);
55   return std::vector<char>(dacl_ptr, dacl_ptr + dacl->AclSize);
56 }
57 
ConvertAclToSddl(const AccessControlList & acl,bool label=false)58 std::wstring ConvertAclToSddl(const AccessControlList& acl,
59                               bool label = false) {
60   SECURITY_DESCRIPTOR sd = {};
61   CHECK(::InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));
62   if (label) {
63     CHECK(::SetSecurityDescriptorSacl(&sd, TRUE, acl.get(), FALSE));
64   } else {
65     CHECK(::SetSecurityDescriptorDacl(&sd, TRUE, acl.get(), FALSE));
66   }
67   LPWSTR sddl_str = nullptr;
68   CHECK(::ConvertSecurityDescriptorToStringSecurityDescriptor(
69       &sd, SDDL_REVISION_1,
70       label ? LABEL_SECURITY_INFORMATION : DACL_SECURITY_INFORMATION, &sddl_str,
71       nullptr));
72   auto sddl_str_ptr = TakeLocalAlloc(sddl_str);
73   std::wstring ret = sddl_str_ptr.get();
74   CHECK(ret.substr(0, 2) == (label ? kSaclPrefix : kDaclPrefix));
75   return ret.substr(2);
76 }
77 }  // namespace
78 
TEST(AccessControlListTest,FromPACL)79 TEST(AccessControlListTest, FromPACL) {
80   auto null_acl = AccessControlList::FromPACL(nullptr);
81   ASSERT_TRUE(null_acl);
82   EXPECT_TRUE(null_acl->is_null());
83   EXPECT_EQ(null_acl->get(), nullptr);
84   EXPECT_EQ(ConvertAclToSddl(*null_acl), kNullAcl);
85 
86   ACL dummy_acl = {};
87   auto invalid_acl = AccessControlList::FromPACL(&dummy_acl);
88   DWORD error = ::GetLastError();
89   EXPECT_FALSE(invalid_acl);
90   EXPECT_EQ(error, DWORD{ERROR_INVALID_ACL});
91 
92   std::vector<char> compare_acl = ConvertSddlToAcl(kFromPACLTest);
93   ASSERT_FALSE(compare_acl.empty());
94   auto test_acl =
95       AccessControlList::FromPACL(reinterpret_cast<ACL*>(compare_acl.data()));
96   ASSERT_TRUE(test_acl);
97   EXPECT_EQ(ConvertAclToSddl(*test_acl), kFromPACLTest);
98 }
99 
TEST(AccessControlListTest,FromMandatoryLabel)100 TEST(AccessControlListTest, FromMandatoryLabel) {
101   auto acl = AccessControlList::FromMandatoryLabel(0, 0, 0);
102   ASSERT_TRUE(acl);
103   EXPECT_EQ(ConvertAclToSddl(*acl, true), kUntrustedLabel);
104   acl = AccessControlList::FromMandatoryLabel(SECURITY_MANDATORY_SYSTEM_RID, 0,
105                                               0);
106   ASSERT_TRUE(acl);
107   EXPECT_EQ(ConvertAclToSddl(*acl, true), kSystemLabel);
108   acl = AccessControlList::FromMandatoryLabel(
109       SECURITY_MANDATORY_SYSTEM_RID, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
110       0);
111   ASSERT_TRUE(acl);
112   EXPECT_EQ(ConvertAclToSddl(*acl, true), kSystemLabelInherit);
113   acl = AccessControlList::FromMandatoryLabel(
114       SECURITY_MANDATORY_SYSTEM_RID, 0,
115       SYSTEM_MANDATORY_LABEL_NO_WRITE_UP | SYSTEM_MANDATORY_LABEL_NO_READ_UP |
116           SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP);
117   ASSERT_TRUE(acl);
118   EXPECT_EQ(ConvertAclToSddl(*acl, true), kSystemLabelPolicy);
119   acl = AccessControlList::FromMandatoryLabel(
120       SECURITY_MANDATORY_SYSTEM_RID, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
121       SYSTEM_MANDATORY_LABEL_NO_WRITE_UP | SYSTEM_MANDATORY_LABEL_NO_READ_UP |
122           SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP);
123   ASSERT_TRUE(acl);
124   EXPECT_EQ(ConvertAclToSddl(*acl, true), kSystemLabelInheritPolicy);
125 }
126 
TEST(AccessControlListTest,Empty)127 TEST(AccessControlListTest, Empty) {
128   AccessControlList acl;
129   EXPECT_FALSE(acl.is_null());
130   ACL* acl_ptr = acl.get();
131   ASSERT_NE(acl_ptr, nullptr);
132   EXPECT_EQ(acl_ptr->AceCount, 0);
133   EXPECT_EQ(acl_ptr->AclSize, sizeof(ACL));
134   EXPECT_EQ(acl_ptr->AclRevision, ACL_REVISION);
135   EXPECT_TRUE(ConvertAclToSddl(acl).empty());
136   AccessControlList acl_clone = acl.Clone();
137   EXPECT_NE(acl.get(), acl_clone.get());
138   EXPECT_TRUE(ConvertAclToSddl(acl_clone).empty());
139 }
140 
TEST(AccessControlListTest,ExplicitAccessEntry)141 TEST(AccessControlListTest, ExplicitAccessEntry) {
142   constexpr DWORD FakeAccess = 0x12345678U;
143   constexpr DWORD FakeInherit = 0x87654321U;
144   Sid sid(WellKnownSid::kWorld);
145   ExplicitAccessEntry ace(sid, SecurityAccessMode::kGrant, FakeAccess,
146                           FakeInherit);
147   EXPECT_EQ(sid, ace.sid());
148   EXPECT_EQ(SecurityAccessMode::kGrant, ace.mode());
149   EXPECT_EQ(FakeAccess, ace.access_mask());
150   EXPECT_EQ(FakeInherit, ace.inheritance());
151   ExplicitAccessEntry ace_clone = ace.Clone();
152   EXPECT_EQ(ace.sid(), ace_clone.sid());
153   EXPECT_NE(ace.sid().GetPSID(), ace_clone.sid().GetPSID());
154   EXPECT_EQ(ace.mode(), ace_clone.mode());
155   EXPECT_EQ(ace.access_mask(), ace_clone.access_mask());
156   EXPECT_EQ(ace.inheritance(), ace_clone.inheritance());
157   ExplicitAccessEntry ace_known(WellKnownSid::kSelf,
158                                 SecurityAccessMode::kRevoke, ~FakeAccess,
159                                 ~FakeInherit);
160   EXPECT_EQ(Sid(WellKnownSid::kSelf), ace_known.sid());
161   EXPECT_EQ(SecurityAccessMode::kRevoke, ace_known.mode());
162   EXPECT_EQ(~FakeAccess, ace_known.access_mask());
163   EXPECT_EQ(~FakeInherit, ace_known.inheritance());
164 }
165 
TEST(AccessControlListTest,SetEntries)166 TEST(AccessControlListTest, SetEntries) {
167   AccessControlList acl;
168   std::vector<ExplicitAccessEntry> ace_list;
169   EXPECT_TRUE(acl.SetEntries(ace_list));
170   EXPECT_EQ(ConvertAclToSddl(acl), L"");
171   ace_list.emplace_back(Sid(WellKnownSid::kWorld), SecurityAccessMode::kGrant,
172                         EVENT_ALL_ACCESS, 0);
173   EXPECT_TRUE(acl.SetEntries(ace_list));
174   EXPECT_EQ(ConvertAclToSddl(acl), kEvent);
175   ace_list.emplace_back(Sid(WellKnownSid::kLocalSystem),
176                         SecurityAccessMode::kDeny, EVENT_MODIFY_STATE,
177                         CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
178   EXPECT_TRUE(acl.SetEntries(ace_list));
179   EXPECT_EQ(ConvertAclToSddl(acl), kEventWithSystemInherit);
180   ace_list.emplace_back(Sid(WellKnownSid::kWorld), SecurityAccessMode::kRevoke,
181                         EVENT_MODIFY_STATE, 0);
182   EXPECT_TRUE(acl.SetEntries(ace_list));
183   EXPECT_EQ(ConvertAclToSddl(acl), kEventSystemOnlyInherit);
184   AccessControlList acl_clone = acl.Clone();
185   EXPECT_NE(acl.get(), acl_clone.get());
186   EXPECT_EQ(ConvertAclToSddl(acl_clone), kEventSystemOnlyInherit);
187 }
188 
TEST(AccessControlListTest,SetEntry)189 TEST(AccessControlListTest, SetEntry) {
190   AccessControlList acl;
191   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kWorld),
192                            SecurityAccessMode::kGrant, READ_CONTROL, 0));
193   EXPECT_EQ(ConvertAclToSddl(acl), kEventReadControl);
194   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kWorld),
195                            SecurityAccessMode::kGrant, EVENT_MODIFY_STATE, 0));
196   EXPECT_EQ(ConvertAclToSddl(acl), kEventReadControlModify);
197   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kWorld), SecurityAccessMode::kSet,
198                            EVENT_ALL_ACCESS, 0));
199   EXPECT_EQ(ConvertAclToSddl(acl), kEvent);
200   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kLocalSystem),
201                            SecurityAccessMode::kDeny, EVENT_MODIFY_STATE,
202                            CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE));
203   EXPECT_EQ(ConvertAclToSddl(acl), kEventWithSystemInherit);
204   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kWorld),
205                            SecurityAccessMode::kRevoke, EVENT_ALL_ACCESS, 0));
206   EXPECT_EQ(ConvertAclToSddl(acl), kEventSystemOnlyInherit);
207 }
208 
TEST(AccessControlListTest,SetEntriesError)209 TEST(AccessControlListTest, SetEntriesError) {
210   AccessControlList acl;
211   std::vector<ExplicitAccessEntry> ace_list;
212   ace_list.emplace_back(Sid(WellKnownSid::kWorld), SecurityAccessMode::kGrant,
213                         EVENT_ALL_ACCESS, 0);
214   EXPECT_TRUE(acl.SetEntries(ace_list));
215   EXPECT_EQ(ConvertAclToSddl(acl), kEvent);
216   // ACL has a maximum capacity of 2^16-1 bytes or 2^16-1 ACEs. Force a fail.
217   while (ace_list.size() < 0x10000) {
218     auto sid =
219         Sid::FromSddlString(L"S-1-5-1234-" + NumberToWString(ace_list.size()));
220     ASSERT_TRUE(sid);
221     ace_list.emplace_back(*sid, SecurityAccessMode::kGrant, GENERIC_ALL, 0);
222   }
223   ::SetLastError(0);
224   bool result = acl.SetEntries(ace_list);
225   DWORD error = ::GetLastError();
226   EXPECT_FALSE(result);
227   EXPECT_EQ(error, DWORD{ERROR_INVALID_PARAMETER});
228 }
229 
TEST(AccessControlListTest,Clear)230 TEST(AccessControlListTest, Clear) {
231   AccessControlList acl;
232   EXPECT_TRUE(acl.SetEntry(Sid(WellKnownSid::kWorld),
233                            SecurityAccessMode::kGrant, READ_CONTROL, 0));
234   EXPECT_EQ(acl.get()->AceCount, 1);
235   acl.Clear();
236   ASSERT_NE(acl.get(), nullptr);
237   EXPECT_EQ(acl.get()->AceCount, 0);
238 }
239 
240 }  // namespace base::win
241