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