xref: /aosp_15_r20/external/cronet/base/win/security_descriptor_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/security_descriptor.h"
6 
7 #include <windows.h>
8 
9 #include <aclapi.h>
10 #include <sddl.h>
11 
12 #include <optional>
13 #include <string>
14 #include <vector>
15 
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_temp_dir.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/unguessable_token.h"
21 #include "base/win/scoped_handle.h"
22 #include "base/win/scoped_localalloc.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 namespace base::win {
26 
27 namespace {
28 
29 constexpr wchar_t kOwnerOnly[] = L"O:BU";
30 constexpr wchar_t kGroupOnly[] = L"G:SY";
31 constexpr wchar_t kDaclOnly[] = L"D:(A;;GA;;;WD)";
32 constexpr wchar_t kProtectedDaclOnly[] = L"D:P(A;;GA;;;WD)";
33 constexpr wchar_t kSaclOnly[] = L"S:(ML;;;;;SI)";
34 constexpr wchar_t kProtectedSaclOnly[] = L"S:P(ML;;;;;SI)";
35 constexpr wchar_t kSaclProtected[] = L"S:P";
36 constexpr wchar_t kFullSd[] = L"O:BUG:SYD:P(A;;GA;;;WD)S:P(ML;;;;;SI)";
37 constexpr wchar_t kFileProtected[] = L"D:P(A;;FA;;;WD)";
38 constexpr wchar_t kFileIntegrity[] = L"S:(ML;;NW;;;ME)";
39 constexpr wchar_t kFileIntegrityInherit[] = L"S:(ML;OICI;NW;;;ME)";
40 constexpr wchar_t kFileProtectedIntegrity[] = L"D:P(A;;FA;;;WD)S:(ML;;NW;;;ME)";
41 constexpr wchar_t kNewDirectory[] = L"D:P(A;OICI;FA;;;WD)";
42 constexpr wchar_t kInheritedFile[] = L"D:(A;ID;FA;;;WD)";
43 constexpr wchar_t kProtectedUsers[] = L"D:P(A;;FA;;;BU)";
44 constexpr wchar_t kEvent[] = L"D:(A;;0x1f0003;;;WD)";
45 constexpr wchar_t kEventWithSystem[] = L"D:(D;;DC;;;SY)(A;;0x1f0003;;;WD)";
46 constexpr wchar_t kEventSystemOnly[] = L"D:(D;;DC;;;SY)";
47 constexpr wchar_t kEventProtectedWithLabel[] =
48     L"D:P(A;;0x1f0003;;;WD)S:(ML;;NW;;;ME)";
49 constexpr wchar_t kEventReadControl[] = L"D:(A;;RC;;;WD)";
50 constexpr wchar_t kEventReadControlModify[] = L"D:(A;;DCRC;;;WD)";
51 constexpr wchar_t kNullDacl[] = L"D:NO_ACCESS_CONTROL";
52 constexpr wchar_t kEmptyDacl[] = L"D:";
53 constexpr wchar_t kAccessCheckSd[] = L"O:SYG:SYD:P(A;;0x1fffff;;;WD)";
54 constexpr SECURITY_INFORMATION kAllSecurityInfo =
55     OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
56     DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION;
57 constexpr SECURITY_INFORMATION kDaclLabelSecurityInfo =
58     DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION;
59 
ConvertSddlToSd(const wchar_t * sddl)60 base::win::ScopedLocalAllocTyped<void> ConvertSddlToSd(const wchar_t* sddl) {
61   PSECURITY_DESCRIPTOR sd = nullptr;
62   CHECK(ConvertStringSecurityDescriptorToSecurityDescriptor(
63       sddl, SDDL_REVISION_1, &sd, nullptr));
64   return TakeLocalAlloc(sd);
65 }
66 
CreateFileWithSd(const FilePath & path,void * sd,bool directory)67 bool CreateFileWithSd(const FilePath& path, void* sd, bool directory) {
68   SECURITY_ATTRIBUTES security_attr = {};
69   security_attr.nLength = sizeof(security_attr);
70   security_attr.lpSecurityDescriptor = sd;
71   if (directory)
72     return !!::CreateDirectory(path.value().c_str(), &security_attr);
73 
74   return ScopedHandle(::CreateFile(path.value().c_str(), GENERIC_ALL, 0,
75                                    &security_attr, CREATE_ALWAYS, 0, nullptr))
76       .is_valid();
77 }
78 
CreateFileWithDacl(const FilePath & path,const wchar_t * sddl,bool directory)79 bool CreateFileWithDacl(const FilePath& path,
80                         const wchar_t* sddl,
81                         bool directory) {
82   auto sd_ptr = ConvertSddlToSd(sddl);
83   CHECK(sd_ptr);
84   return CreateFileWithSd(path, sd_ptr.get(), directory);
85 }
86 
CreateEventWithDacl(const wchar_t * name,const wchar_t * sddl)87 base::win::ScopedHandle CreateEventWithDacl(const wchar_t* name,
88                                             const wchar_t* sddl) {
89   auto sd_ptr = ConvertSddlToSd(sddl);
90   CHECK(sd_ptr);
91   SECURITY_ATTRIBUTES security_attr = {};
92   security_attr.nLength = sizeof(security_attr);
93   security_attr.lpSecurityDescriptor = sd_ptr.get();
94   return base::win::ScopedHandle(
95       ::CreateEvent(&security_attr, FALSE, FALSE, name));
96 }
97 
DuplicateHandle(const base::win::ScopedHandle & handle,DWORD access_mask)98 base::win::ScopedHandle DuplicateHandle(const base::win::ScopedHandle& handle,
99                                         DWORD access_mask) {
100   HANDLE dup_handle;
101   CHECK(::DuplicateHandle(::GetCurrentProcess(), handle.get(),
102                           ::GetCurrentProcess(), &dup_handle, access_mask,
103                           FALSE, 0));
104   return base::win::ScopedHandle(dup_handle);
105 }
106 
ExpectSid(const std::optional<Sid> & sid,WellKnownSid known_sid)107 void ExpectSid(const std::optional<Sid>& sid, WellKnownSid known_sid) {
108   ASSERT_TRUE(sid);
109   EXPECT_EQ(*sid, Sid(known_sid));
110 }
111 
AccessCheckError(const std::optional<AccessCheckResult> & result,DWORD expected)112 void AccessCheckError(const std::optional<AccessCheckResult>& result,
113                       DWORD expected) {
114   EXPECT_FALSE(result.has_value());
115   EXPECT_EQ(::GetLastError(), expected);
116 }
117 
AccessCheckStatusError(const std::optional<AccessCheckResult> & result,DWORD expected)118 void AccessCheckStatusError(const std::optional<AccessCheckResult>& result,
119                             DWORD expected) {
120   ASSERT_TRUE(result.has_value());
121   EXPECT_FALSE(result->access_status);
122   EXPECT_EQ(::GetLastError(), expected);
123 }
124 
AccessCheckTest(const std::optional<AccessCheckResult> & result,ACCESS_MASK expected_access)125 void AccessCheckTest(const std::optional<AccessCheckResult>& result,
126                      ACCESS_MASK expected_access) {
127   ASSERT_TRUE(result.has_value());
128   EXPECT_TRUE(result->access_status);
129   EXPECT_EQ(result->granted_access, expected_access);
130 }
131 
132 template <typename T>
AccessCheckTest(T type,ACCESS_MASK generic_read,ACCESS_MASK generic_write,ACCESS_MASK generic_execute,ACCESS_MASK generic_all)133 void AccessCheckTest(T type,
134                      ACCESS_MASK generic_read,
135                      ACCESS_MASK generic_write,
136                      ACCESS_MASK generic_execute,
137                      ACCESS_MASK generic_all) {
138   std::optional<SecurityDescriptor> sd =
139       SecurityDescriptor::FromSddl(kAccessCheckSd);
140   ASSERT_TRUE(sd);
141   std::optional<AccessToken> token = AccessToken::FromCurrentProcess(
142       /*impersonation=*/true, TOKEN_ADJUST_DEFAULT);
143   ASSERT_TRUE(token.has_value());
144   AccessCheckTest(sd->AccessCheck(*token, GENERIC_READ, type), generic_read);
145   AccessCheckTest(sd->AccessCheck(*token, GENERIC_WRITE, type), generic_write);
146   AccessCheckTest(sd->AccessCheck(*token, GENERIC_EXECUTE, type),
147                   generic_execute);
148   AccessCheckTest(sd->AccessCheck(*token, GENERIC_ALL, type), generic_all);
149   AccessCheckTest(sd->AccessCheck(*token, 0x1fffff, type), 0x1fffff);
150   AccessCheckTest(sd->AccessCheck(*token, MAXIMUM_ALLOWED, type), 0x1fffff);
151   ASSERT_TRUE(sd->SetMandatoryLabel(SECURITY_MANDATORY_LOW_RID, 0,
152                                     SYSTEM_MANDATORY_LABEL_NO_WRITE_UP));
153   ASSERT_TRUE(token->SetIntegrityLevel(SECURITY_MANDATORY_UNTRUSTED_RID));
154   AccessCheckTest(sd->AccessCheck(*token, GENERIC_READ, type), generic_read);
155   AccessCheckTest(sd->AccessCheck(*token, GENERIC_EXECUTE, type),
156                   generic_execute);
157   AccessCheckStatusError(sd->AccessCheck(*token, GENERIC_WRITE, type),
158                          ERROR_ACCESS_DENIED);
159   ASSERT_TRUE(sd->SetMandatoryLabel(SECURITY_MANDATORY_UNTRUSTED_RID, 0,
160                                     SYSTEM_MANDATORY_LABEL_NO_WRITE_UP));
161   AccessCheckTest(sd->AccessCheck(*token, GENERIC_ALL, type), generic_all);
162 }
163 
AccessCheckTest(const GENERIC_MAPPING & type)164 void AccessCheckTest(const GENERIC_MAPPING& type) {
165   AccessCheckTest(type, type.GenericRead, type.GenericWrite,
166                   type.GenericExecute, type.GenericAll);
167 }
168 
169 }  // namespace
170 
TEST(SecurityDescriptorTest,Initialize)171 TEST(SecurityDescriptorTest, Initialize) {
172   SecurityDescriptor sd;
173   EXPECT_FALSE(sd.owner());
174   EXPECT_FALSE(sd.group());
175   EXPECT_FALSE(sd.dacl());
176   EXPECT_FALSE(sd.dacl_protected());
177   EXPECT_FALSE(sd.sacl());
178   EXPECT_FALSE(sd.sacl_protected());
179 
180   sd.set_owner(Sid(WellKnownSid::kBuiltinUsers));
181   ExpectSid(sd.owner(), WellKnownSid::kBuiltinUsers);
182   sd.clear_owner();
183   EXPECT_FALSE(sd.owner());
184   sd.set_group(Sid(WellKnownSid::kLocalSystem));
185   ExpectSid(sd.group(), WellKnownSid::kLocalSystem);
186   sd.clear_group();
187   EXPECT_FALSE(sd.group());
188   sd.set_dacl(AccessControlList());
189   EXPECT_TRUE(sd.dacl());
190   EXPECT_FALSE(sd.dacl()->is_null());
191   sd.clear_dacl();
192   EXPECT_FALSE(sd.dacl());
193   sd.set_sacl(AccessControlList());
194   EXPECT_TRUE(sd.sacl());
195   EXPECT_FALSE(sd.sacl()->is_null());
196   sd.clear_sacl();
197   EXPECT_FALSE(sd.sacl());
198 }
199 
TEST(SecurityDescriptorTest,FromPointer)200 TEST(SecurityDescriptorTest, FromPointer) {
201   auto sd = SecurityDescriptor::FromPointer(nullptr);
202   EXPECT_FALSE(sd);
203   SECURITY_DESCRIPTOR sd_abs = {};
204   sd = SecurityDescriptor::FromPointer(&sd_abs);
205   EXPECT_FALSE(sd);
206   sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kOwnerOnly).get());
207   ASSERT_TRUE(sd);
208   ExpectSid(sd->owner(), WellKnownSid::kBuiltinUsers);
209   sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kGroupOnly).get());
210   ASSERT_TRUE(sd);
211   ExpectSid(sd->group(), WellKnownSid::kLocalSystem);
212   sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kDaclOnly).get());
213   ASSERT_TRUE(sd);
214   EXPECT_TRUE(sd->dacl());
215   EXPECT_FALSE(sd->dacl_protected());
216   sd = SecurityDescriptor::FromPointer(
217       ConvertSddlToSd(kProtectedDaclOnly).get());
218   ASSERT_TRUE(sd);
219   EXPECT_TRUE(sd->dacl());
220   EXPECT_TRUE(sd->dacl_protected());
221   sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kSaclOnly).get());
222   ASSERT_TRUE(sd);
223   EXPECT_TRUE(sd->sacl());
224   EXPECT_FALSE(sd->sacl_protected());
225   sd = SecurityDescriptor::FromPointer(
226       ConvertSddlToSd(kProtectedSaclOnly).get());
227   ASSERT_TRUE(sd);
228   EXPECT_TRUE(sd->sacl());
229   EXPECT_TRUE(sd->sacl_protected());
230   sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kFullSd).get());
231   ASSERT_TRUE(sd);
232   ExpectSid(sd->owner(), WellKnownSid::kBuiltinUsers);
233   ExpectSid(sd->group(), WellKnownSid::kLocalSystem);
234   EXPECT_TRUE(sd->dacl());
235   EXPECT_TRUE(sd->dacl_protected());
236   EXPECT_TRUE(sd->sacl());
237   EXPECT_TRUE(sd->sacl_protected());
238 }
239 
TEST(SecurityDescriptorTest,ToSddl)240 TEST(SecurityDescriptorTest, ToSddl) {
241   auto sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kFullSd).get());
242   ASSERT_TRUE(sd);
243   EXPECT_EQ(sd->ToSddl(0), L"");
244   EXPECT_EQ(sd->ToSddl(OWNER_SECURITY_INFORMATION), kOwnerOnly);
245   EXPECT_EQ(sd->ToSddl(GROUP_SECURITY_INFORMATION), kGroupOnly);
246   EXPECT_EQ(sd->ToSddl(DACL_SECURITY_INFORMATION), kProtectedDaclOnly);
247   EXPECT_EQ(sd->ToSddl(LABEL_SECURITY_INFORMATION), kProtectedSaclOnly);
248   EXPECT_EQ(sd->ToSddl(SACL_SECURITY_INFORMATION), kSaclProtected);
249   EXPECT_EQ(sd->ToSddl(kAllSecurityInfo), kFullSd);
250   SecurityDescriptor empty_sd;
251   empty_sd.set_dacl(AccessControlList());
252   EXPECT_EQ(empty_sd.ToSddl(DACL_SECURITY_INFORMATION), kEmptyDacl);
253 }
254 
TEST(SecurityDescriptorTest,FromSddl)255 TEST(SecurityDescriptorTest, FromSddl) {
256   auto sd = SecurityDescriptor::FromSddl(L"");
257   EXPECT_TRUE(sd);
258   EXPECT_FALSE(sd->owner());
259   EXPECT_FALSE(sd->group());
260   EXPECT_FALSE(sd->dacl());
261   EXPECT_FALSE(sd->sacl());
262   sd = SecurityDescriptor::FromSddl(kOwnerOnly);
263   ASSERT_TRUE(sd);
264   ExpectSid(sd->owner(), WellKnownSid::kBuiltinUsers);
265   sd = SecurityDescriptor::FromSddl(kGroupOnly);
266   ASSERT_TRUE(sd);
267   ExpectSid(sd->group(), WellKnownSid::kLocalSystem);
268   sd = SecurityDescriptor::FromSddl(kDaclOnly);
269   ASSERT_TRUE(sd);
270   EXPECT_TRUE(sd->dacl());
271   EXPECT_FALSE(sd->dacl_protected());
272   sd = SecurityDescriptor::FromSddl(kProtectedDaclOnly);
273   ASSERT_TRUE(sd);
274   EXPECT_TRUE(sd->dacl());
275   EXPECT_TRUE(sd->dacl_protected());
276   sd = SecurityDescriptor::FromSddl(kSaclOnly);
277   ASSERT_TRUE(sd);
278   EXPECT_TRUE(sd->sacl());
279   EXPECT_FALSE(sd->sacl_protected());
280   sd = SecurityDescriptor::FromSddl(kProtectedSaclOnly);
281   ASSERT_TRUE(sd);
282   EXPECT_TRUE(sd->sacl());
283   EXPECT_TRUE(sd->sacl_protected());
284   sd = SecurityDescriptor::FromSddl(kFullSd);
285   ASSERT_TRUE(sd);
286   ExpectSid(sd->owner(), WellKnownSid::kBuiltinUsers);
287   ExpectSid(sd->group(), WellKnownSid::kLocalSystem);
288   EXPECT_TRUE(sd->dacl());
289   EXPECT_TRUE(sd->dacl_protected());
290   EXPECT_TRUE(sd->sacl());
291   EXPECT_TRUE(sd->sacl_protected());
292   sd = SecurityDescriptor::FromSddl(kNullDacl);
293   ASSERT_TRUE(sd);
294   ASSERT_TRUE(sd->dacl());
295   EXPECT_TRUE(sd->dacl()->is_null());
296 }
297 
TEST(SecurityDescriptorTest,Clone)298 TEST(SecurityDescriptorTest, Clone) {
299   SecurityDescriptor cloned = SecurityDescriptor().Clone();
300   EXPECT_FALSE(cloned.owner());
301   EXPECT_FALSE(cloned.group());
302   EXPECT_FALSE(cloned.dacl());
303   EXPECT_FALSE(cloned.dacl_protected());
304   EXPECT_FALSE(cloned.sacl());
305   EXPECT_FALSE(cloned.sacl_protected());
306   auto sd = SecurityDescriptor::FromSddl(kFullSd);
307   ASSERT_TRUE(sd);
308   cloned = sd->Clone();
309   EXPECT_EQ(sd->owner(), cloned.owner());
310   EXPECT_NE(sd->owner()->GetPSID(), cloned.owner()->GetPSID());
311   EXPECT_EQ(sd->group(), cloned.group());
312   EXPECT_NE(sd->group()->GetPSID(), cloned.group()->GetPSID());
313   EXPECT_NE(sd->dacl()->get(), cloned.dacl()->get());
314   EXPECT_EQ(sd->dacl_protected(), cloned.dacl_protected());
315   EXPECT_NE(sd->sacl()->get(), cloned.sacl()->get());
316   EXPECT_EQ(sd->sacl_protected(), cloned.sacl_protected());
317 }
318 
TEST(SecurityDescriptorTest,ToAbsolute)319 TEST(SecurityDescriptorTest, ToAbsolute) {
320   auto sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kFullSd).get());
321   ASSERT_TRUE(sd);
322   SECURITY_DESCRIPTOR sd_abs;
323   sd->ToAbsolute(sd_abs);
324   EXPECT_EQ(sd_abs.Revision, SECURITY_DESCRIPTOR_REVISION);
325   EXPECT_EQ(sd_abs.Control, SE_DACL_PRESENT | SE_DACL_PROTECTED |
326                                 SE_SACL_PRESENT | SE_SACL_PROTECTED);
327   EXPECT_EQ(sd_abs.Owner, sd->owner()->GetPSID());
328   EXPECT_EQ(sd_abs.Group, sd->group()->GetPSID());
329   EXPECT_EQ(sd_abs.Dacl, sd->dacl()->get());
330   EXPECT_EQ(sd_abs.Sacl, sd->sacl()->get());
331 }
332 
TEST(SecurityDescriptorTest,ToSelfRelative)333 TEST(SecurityDescriptorTest, ToSelfRelative) {
334   auto sd = SecurityDescriptor::FromPointer(ConvertSddlToSd(kFullSd).get());
335   ASSERT_TRUE(sd);
336   auto sd_rel = sd->ToSelfRelative();
337   ASSERT_TRUE(sd_rel);
338   EXPECT_TRUE(sd_rel->get());
339   EXPECT_EQ(sd_rel->size(), ::GetSecurityDescriptorLength(sd_rel->get()));
340   sd = SecurityDescriptor::FromPointer(sd_rel->get());
341   ASSERT_TRUE(sd);
342   EXPECT_EQ(sd->ToSddl(kAllSecurityInfo), kFullSd);
343 }
344 
TEST(SecurityDescriptorTest,SetMandatoryLabel)345 TEST(SecurityDescriptorTest, SetMandatoryLabel) {
346   SecurityDescriptor sd;
347   EXPECT_FALSE(sd.sacl());
348   sd.SetMandatoryLabel(SECURITY_MANDATORY_SYSTEM_RID, 0, 0);
349   EXPECT_TRUE(sd.sacl());
350   EXPECT_EQ(sd.ToSddl(LABEL_SECURITY_INFORMATION), kSaclOnly);
351   sd.SetMandatoryLabel(SECURITY_MANDATORY_MEDIUM_RID,
352                        OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE,
353                        SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
354   EXPECT_TRUE(sd.sacl());
355   EXPECT_EQ(sd.ToSddl(LABEL_SECURITY_INFORMATION), kFileIntegrityInherit);
356 }
357 
TEST(SecurityDescriptorTest,SetDaclEntries)358 TEST(SecurityDescriptorTest, SetDaclEntries) {
359   SecurityDescriptor sd;
360   EXPECT_FALSE(sd.dacl());
361   std::vector<ExplicitAccessEntry> ace_list;
362   EXPECT_TRUE(sd.SetDaclEntries(ace_list));
363   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEmptyDacl);
364   ace_list.emplace_back(Sid(WellKnownSid::kWorld), SecurityAccessMode::kGrant,
365                         EVENT_ALL_ACCESS, 0);
366   EXPECT_TRUE(sd.SetDaclEntries(ace_list));
367   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEvent);
368   ace_list.emplace_back(Sid(WellKnownSid::kLocalSystem),
369                         SecurityAccessMode::kDeny, EVENT_MODIFY_STATE, 0);
370   EXPECT_TRUE(sd.SetDaclEntries(ace_list));
371   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventWithSystem);
372   ace_list.emplace_back(Sid(WellKnownSid::kWorld), SecurityAccessMode::kRevoke,
373                         EVENT_MODIFY_STATE, 0);
374   EXPECT_TRUE(sd.SetDaclEntries(ace_list));
375   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventSystemOnly);
376 }
377 
TEST(SecurityDescriptorTest,SetDaclEntry)378 TEST(SecurityDescriptorTest, SetDaclEntry) {
379   SecurityDescriptor sd;
380   EXPECT_TRUE(sd.SetDaclEntry(Sid(WellKnownSid::kWorld),
381                               SecurityAccessMode::kGrant, READ_CONTROL, 0));
382   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventReadControl);
383   EXPECT_TRUE(sd.SetDaclEntry(Sid(WellKnownSid::kWorld),
384                               SecurityAccessMode::kGrant, EVENT_MODIFY_STATE,
385                               0));
386   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventReadControlModify);
387   EXPECT_TRUE(sd.SetDaclEntry(Sid(WellKnownSid::kWorld),
388                               SecurityAccessMode::kSet, EVENT_ALL_ACCESS, 0));
389   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEvent);
390   EXPECT_TRUE(sd.SetDaclEntry(Sid(WellKnownSid::kLocalSystem),
391                               SecurityAccessMode::kDeny, EVENT_MODIFY_STATE,
392                               0));
393   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventWithSystem);
394   EXPECT_TRUE(sd.SetDaclEntry(Sid(WellKnownSid::kWorld),
395                               SecurityAccessMode::kRevoke, EVENT_ALL_ACCESS,
396                               0));
397   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventSystemOnly);
398   sd.clear_dacl();
399   EXPECT_TRUE(sd.SetDaclEntry(WellKnownSid::kWorld, SecurityAccessMode::kGrant,
400                               READ_CONTROL, 0));
401   EXPECT_EQ(sd.ToSddl(DACL_SECURITY_INFORMATION), kEventReadControl);
402 }
403 
TEST(SecurityDescriptorTest,FromFile)404 TEST(SecurityDescriptorTest, FromFile) {
405   ScopedTempDir temp_dir;
406   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
407   FilePath path = temp_dir.GetPath().Append(L"test");
408   EXPECT_FALSE(SecurityDescriptor::FromFile(path, kAllSecurityInfo));
409   ASSERT_TRUE(CreateFileWithDacl(path, kFileProtectedIntegrity, false));
410   auto sd = SecurityDescriptor::FromFile(path, kAllSecurityInfo);
411   ASSERT_TRUE(sd);
412   EXPECT_EQ(sd->ToSddl(DACL_SECURITY_INFORMATION), kFileProtected);
413   sd = SecurityDescriptor::FromFile(path, LABEL_SECURITY_INFORMATION);
414   ASSERT_TRUE(sd);
415   EXPECT_EQ(sd->ToSddl(LABEL_SECURITY_INFORMATION), kFileIntegrity);
416   sd = SecurityDescriptor::FromFile(path, kAllSecurityInfo);
417   ASSERT_TRUE(sd);
418   EXPECT_EQ(sd->ToSddl(kDaclLabelSecurityInfo), kFileProtectedIntegrity);
419 }
420 
TEST(SecurityDescriptorTest,WriteToFile)421 TEST(SecurityDescriptorTest, WriteToFile) {
422   ScopedTempDir temp_dir;
423   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
424   FilePath dir_path = temp_dir.GetPath().Append(L"test");
425   ASSERT_TRUE(CreateFileWithDacl(dir_path, kNewDirectory, true));
426   FilePath path = dir_path.Append(L"test");
427   ASSERT_TRUE(CreateFileWithSd(path, nullptr, false));
428 
429   auto curr_sd = SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
430   ASSERT_TRUE(curr_sd);
431   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kInheritedFile);
432 
433   AccessControlList new_acl;
434   EXPECT_TRUE(new_acl.SetEntry(Sid(WellKnownSid::kBuiltinUsers),
435                                SecurityAccessMode::kGrant, FILE_ALL_ACCESS, 0));
436   SecurityDescriptor new_sd;
437   new_sd.set_dacl(new_acl);
438   new_sd.set_dacl_protected(true);
439   EXPECT_TRUE(new_sd.WriteToFile(path, DACL_SECURITY_INFORMATION));
440   curr_sd = SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
441   ASSERT_TRUE(curr_sd);
442   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kProtectedUsers);
443 
444   SecurityDescriptor empty_sd;
445   empty_sd.set_dacl(AccessControlList{});
446   EXPECT_TRUE(empty_sd.WriteToFile(path, DACL_SECURITY_INFORMATION));
447   curr_sd = SecurityDescriptor::FromFile(path, DACL_SECURITY_INFORMATION);
448   ASSERT_TRUE(curr_sd);
449   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kInheritedFile);
450 
451   auto label_acl = AccessControlList::FromMandatoryLabel(
452       SECURITY_MANDATORY_MEDIUM_RID, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
453   ASSERT_TRUE(label_acl);
454   SecurityDescriptor label_sd;
455   label_sd.set_sacl(*label_acl);
456   EXPECT_TRUE(label_sd.WriteToFile(path, LABEL_SECURITY_INFORMATION));
457   curr_sd = SecurityDescriptor::FromFile(path, LABEL_SECURITY_INFORMATION);
458   ASSERT_TRUE(curr_sd);
459   EXPECT_EQ(curr_sd->ToSddl(LABEL_SECURITY_INFORMATION), kFileIntegrity);
460 }
461 
TEST(SecurityDescriptorTest,FromName)462 TEST(SecurityDescriptorTest, FromName) {
463   std::wstring name =
464       base::ASCIIToWide(base::UnguessableToken::Create().ToString());
465   EXPECT_FALSE(SecurityDescriptor::FromName(
466       name.c_str(), SecurityObjectType::kKernel, kAllSecurityInfo));
467   base::win::ScopedHandle handle = CreateEventWithDacl(name.c_str(), kEvent);
468   ASSERT_TRUE(handle.is_valid());
469   auto curr_sd = SecurityDescriptor::FromName(
470       name.c_str(), SecurityObjectType::kKernel, kAllSecurityInfo);
471   ASSERT_TRUE(curr_sd);
472   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kEvent);
473   EXPECT_TRUE(SecurityDescriptor::FromName(
474       L"MACHINE\\SOFTWARE", SecurityObjectType::kRegistry, kAllSecurityInfo));
475   EXPECT_TRUE(SecurityDescriptor::FromName(L".", SecurityObjectType::kFile,
476                                            kAllSecurityInfo));
477   EXPECT_FALSE(SecurityDescriptor::FromName(
478       L"WinSta0", SecurityObjectType::kWindowStation, kAllSecurityInfo));
479   EXPECT_FALSE(SecurityDescriptor::FromName(
480       L"Default", SecurityObjectType::kDesktop, kAllSecurityInfo));
481 }
482 
TEST(SecurityDescriptorTest,WriteToName)483 TEST(SecurityDescriptorTest, WriteToName) {
484   std::wstring name =
485       base::ASCIIToWide(base::UnguessableToken::Create().ToString());
486   EXPECT_FALSE(SecurityDescriptor().WriteToName(
487       name.c_str(), SecurityObjectType::kKernel, kAllSecurityInfo));
488   base::win::ScopedHandle handle = CreateEventWithDacl(name.c_str(), kEvent);
489   ASSERT_TRUE(handle.is_valid());
490   auto curr_sd = SecurityDescriptor::FromName(
491       name.c_str(), SecurityObjectType::kKernel, kAllSecurityInfo);
492   ASSERT_TRUE(curr_sd);
493   curr_sd->set_dacl_protected(true);
494   curr_sd->SetMandatoryLabel(SECURITY_MANDATORY_MEDIUM_RID, 0,
495                              SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
496 
497   EXPECT_TRUE(curr_sd->WriteToName(name.c_str(), SecurityObjectType::kKernel,
498                                    kDaclLabelSecurityInfo));
499 
500   curr_sd = SecurityDescriptor::FromName(
501       name.c_str(), SecurityObjectType::kKernel, kAllSecurityInfo);
502   ASSERT_TRUE(curr_sd);
503   EXPECT_EQ(curr_sd->ToSddl(kDaclLabelSecurityInfo), kEventProtectedWithLabel);
504 }
505 
TEST(SecurityDescriptorTest,FromHandle)506 TEST(SecurityDescriptorTest, FromHandle) {
507   EXPECT_FALSE(SecurityDescriptor::FromHandle(
508       nullptr, SecurityObjectType::kKernel, kAllSecurityInfo));
509   auto handle = CreateEventWithDacl(nullptr, kEvent);
510   ASSERT_TRUE(handle.is_valid());
511   auto curr_sd = SecurityDescriptor::FromHandle(
512       handle.get(), SecurityObjectType::kKernel, kAllSecurityInfo);
513   ASSERT_TRUE(curr_sd);
514   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kEvent);
515   auto dup_handle = DuplicateHandle(handle, EVENT_MODIFY_STATE);
516   EXPECT_FALSE(SecurityDescriptor::FromHandle(
517       dup_handle.get(), SecurityObjectType::kKernel, kAllSecurityInfo));
518   EXPECT_TRUE(SecurityDescriptor::FromHandle(::GetProcessWindowStation(),
519                                              SecurityObjectType::kWindowStation,
520                                              kAllSecurityInfo));
521   EXPECT_TRUE(SecurityDescriptor::FromHandle(
522       ::GetThreadDesktop(::GetCurrentThreadId()), SecurityObjectType::kDesktop,
523       kAllSecurityInfo));
524 }
525 
TEST(SecurityDescriptorTest,WriteToHandle)526 TEST(SecurityDescriptorTest, WriteToHandle) {
527   EXPECT_FALSE(SecurityDescriptor().WriteToHandle(
528       nullptr, SecurityObjectType::kKernel, kAllSecurityInfo));
529   base::win::ScopedHandle handle = CreateEventWithDacl(nullptr, kEvent);
530   ASSERT_TRUE(handle.is_valid());
531   auto curr_sd = SecurityDescriptor::FromHandle(
532       handle.get(), SecurityObjectType::kKernel, kAllSecurityInfo);
533   EXPECT_EQ(curr_sd->ToSddl(DACL_SECURITY_INFORMATION), kEvent);
534   ASSERT_TRUE(curr_sd);
535   curr_sd->set_dacl_protected(true);
536   curr_sd->SetMandatoryLabel(SECURITY_MANDATORY_MEDIUM_RID, 0,
537                              SYSTEM_MANDATORY_LABEL_NO_WRITE_UP);
538 
539   EXPECT_TRUE(curr_sd->WriteToHandle(handle.get(), SecurityObjectType::kKernel,
540                                      kDaclLabelSecurityInfo));
541 
542   curr_sd = SecurityDescriptor::FromHandle(
543       handle.get(), SecurityObjectType::kKernel, kAllSecurityInfo);
544   ASSERT_TRUE(curr_sd);
545   EXPECT_EQ(curr_sd->ToSddl(kDaclLabelSecurityInfo), kEventProtectedWithLabel);
546 }
547 
TEST(SecurityDescriptorTest,AccessCheck)548 TEST(SecurityDescriptorTest, AccessCheck) {
549   std::optional<SecurityDescriptor> sd =
550       SecurityDescriptor::FromSddl(kAccessCheckSd);
551   ASSERT_TRUE(sd);
552   std::optional<AccessToken> token = AccessToken::FromCurrentProcess();
553   ASSERT_TRUE(token);
554   AccessCheckError(sd->AccessCheck(*token, 1, SecurityObjectType::kFile),
555                    ERROR_NO_IMPERSONATION_TOKEN);
556   token = AccessToken::FromCurrentProcess(/*impersonation=*/true);
557   ASSERT_TRUE(token);
558   AccessCheckError(sd->AccessCheck(*token, 1, SecurityObjectType::kKernel),
559                    ERROR_INVALID_PARAMETER);
560   sd->set_dacl(AccessControlList());
561   AccessCheckStatusError(sd->AccessCheck(*token, 1, SecurityObjectType::kFile),
562                          ERROR_ACCESS_DENIED);
563   sd->clear_owner();
564   AccessCheckError(sd->AccessCheck(*token, 1, SecurityObjectType::kFile),
565                    ERROR_INVALID_SECURITY_DESCR);
566   AccessCheckTest({1, 2, 4, 8});
567   AccessCheckTest(SecurityObjectType::kFile, FILE_GENERIC_READ,
568                   FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS);
569   AccessCheckTest(SecurityObjectType::kRegistry, KEY_READ, KEY_WRITE,
570                   KEY_EXECUTE, KEY_ALL_ACCESS);
571   AccessCheckTest(
572       SecurityObjectType::kDesktop,
573       STANDARD_RIGHTS_READ | DESKTOP_READOBJECTS | DESKTOP_ENUMERATE,
574       STANDARD_RIGHTS_WRITE | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU |
575           DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD |
576           DESKTOP_JOURNALPLAYBACK | DESKTOP_WRITEOBJECTS,
577       STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP,
578       STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
579           DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK |
580           DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP |
581           DESKTOP_WRITEOBJECTS);
582   AccessCheckTest(
583       SecurityObjectType::kWindowStation,
584       STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE |
585           WINSTA_READATTRIBUTES | WINSTA_READSCREEN,
586       STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP |
587           WINSTA_WRITEATTRIBUTES,
588       STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS,
589       STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD |
590           WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP |
591           WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |
592           WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES);
593 }
594 
595 }  // namespace base::win
596