1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "base/win_sandbox.h"
31 
32 #include "base/scoped_handle.h"
33 #include "testing/base/public/googletest.h"
34 #include "testing/base/public/gunit.h"
35 
36 namespace mozc {
37 namespace {
38 
39 class TestableWinSandbox : public WinSandbox {
40  public:
41   // Change access rights.
42   using WinSandbox::GetSDDL;
43 
44  private:
45   DISALLOW_IMPLICIT_CONSTRUCTORS(TestableWinSandbox);
46 };
47 
VerifySidContained(const std::vector<Sid> sids,WELL_KNOWN_SID_TYPE expected_well_known_sid)48 void VerifySidContained(const std::vector<Sid> sids,
49                         WELL_KNOWN_SID_TYPE expected_well_known_sid) {
50   Sid expected_sid(expected_well_known_sid);
51   for (size_t i = 0; i < sids.size(); ++i) {
52     Sid temp_sid = sids[i];
53     if (::EqualSid(expected_sid.GetPSID(), temp_sid.GetPSID())) {
54       // Found!
55       return;
56     }
57   }
58   EXPECT_TRUE(false) << "Not found. Expected SID: " << expected_well_known_sid;
59 }
60 
TEST(WinSandboxTest,GetSidsToDisable)61 TEST(WinSandboxTest, GetSidsToDisable) {
62   HANDLE process_token_ret = NULL;
63   ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
64                      &process_token_ret);
65   ScopedHandle process_token(process_token_ret);
66 
67   const std::vector<Sid> lockdown = WinSandbox::GetSidsToDisable(
68       process_token.get(), WinSandbox::USER_LOCKDOWN);
69   const std::vector<Sid> restricted = WinSandbox::GetSidsToDisable(
70       process_token.get(), WinSandbox::USER_RESTRICTED);
71   const std::vector<Sid> limited = WinSandbox::GetSidsToDisable(
72       process_token.get(), WinSandbox::USER_LIMITED);
73   const std::vector<Sid> interactive = WinSandbox::GetSidsToDisable(
74       process_token.get(), WinSandbox::USER_INTERACTIVE);
75   const std::vector<Sid> non_admin = WinSandbox::GetSidsToDisable(
76       process_token.get(), WinSandbox::USER_NON_ADMIN);
77   const std::vector<Sid> restricted_same_access = WinSandbox::GetSidsToDisable(
78       process_token.get(), WinSandbox::USER_RESTRICTED_SAME_ACCESS);
79   const std::vector<Sid> unprotect = WinSandbox::GetSidsToDisable(
80       process_token.get(), WinSandbox::USER_UNPROTECTED);
81 
82   EXPECT_TRUE(restricted.size() == lockdown.size());
83   VerifySidContained(lockdown, WinBuiltinUsersSid);
84 
85   VerifySidContained(limited, WinAuthenticatedUserSid);
86 
87   EXPECT_TRUE(non_admin.size() == interactive.size());
88 
89   EXPECT_EQ(0, restricted_same_access.size());
90 
91   EXPECT_EQ(0, unprotect.size());
92 }
93 
TEST(WinSandboxTest,GetPrivilegesToDisable)94 TEST(WinSandboxTest, GetPrivilegesToDisable) {
95   HANDLE process_token_ret = NULL;
96   ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
97                      &process_token_ret);
98   ScopedHandle process_token(process_token_ret);
99 
100   const std::vector<LUID> lockdown = WinSandbox::GetPrivilegesToDisable(
101       process_token.get(), WinSandbox::USER_LOCKDOWN);
102   const std::vector<LUID> restricted = WinSandbox::GetPrivilegesToDisable(
103       process_token.get(), WinSandbox::USER_RESTRICTED);
104   const std::vector<LUID> limited = WinSandbox::GetPrivilegesToDisable(
105       process_token.get(), WinSandbox::USER_LIMITED);
106   const std::vector<LUID> interactive = WinSandbox::GetPrivilegesToDisable(
107       process_token.get(), WinSandbox::USER_INTERACTIVE);
108   const std::vector<LUID> non_admin = WinSandbox::GetPrivilegesToDisable(
109       process_token.get(), WinSandbox::USER_NON_ADMIN);
110   const std::vector<LUID> restricted_same_access =
111       WinSandbox::GetPrivilegesToDisable(
112           process_token.get(), WinSandbox::USER_RESTRICTED_SAME_ACCESS);
113   const std::vector<LUID> unprotect = WinSandbox::GetPrivilegesToDisable(
114       process_token.get(), WinSandbox::USER_UNPROTECTED);
115 
116   EXPECT_EQ(0, restricted_same_access.size());
117   EXPECT_EQ(0, unprotect.size());
118 }
119 
TEST(WinSandboxTest,GetSidsToRestrict)120 TEST(WinSandboxTest, GetSidsToRestrict) {
121   HANDLE process_token_ret = NULL;
122   ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS,
123                      &process_token_ret);
124   ScopedHandle process_token(process_token_ret);
125 
126   const std::vector<Sid> lockdown = WinSandbox::GetSidsToRestrict(
127       process_token.get(), WinSandbox::USER_LOCKDOWN);
128   const std::vector<Sid> restricted = WinSandbox::GetSidsToRestrict(
129       process_token.get(), WinSandbox::USER_RESTRICTED);
130   const std::vector<Sid> limited = WinSandbox::GetSidsToRestrict(
131       process_token.get(), WinSandbox::USER_LIMITED);
132   const std::vector<Sid> interactive = WinSandbox::GetSidsToRestrict(
133       process_token.get(), WinSandbox::USER_INTERACTIVE);
134   const std::vector<Sid> non_admin = WinSandbox::GetSidsToRestrict(
135       process_token.get(), WinSandbox::USER_NON_ADMIN);
136   const std::vector<Sid> restricted_same_access = WinSandbox::GetSidsToRestrict(
137           process_token.get(), WinSandbox::USER_RESTRICTED_SAME_ACCESS);
138   const std::vector<Sid> unprotect = WinSandbox::GetSidsToRestrict(
139       process_token.get(), WinSandbox::USER_UNPROTECTED);
140 
141   EXPECT_EQ(1, lockdown.size());
142   VerifySidContained(lockdown, WinNullSid);
143 
144   VerifySidContained(limited, WinBuiltinUsersSid);
145 
146   VerifySidContained(interactive, WinBuiltinUsersSid);
147 }
148 
149 const wchar_t kDummyUserSID[] = L"S-8";
150 const wchar_t kDummyGroupSID[] = L"S-9";
151 
GetSDDLForVista(WinSandbox::ObjectSecurityType type)152 std::wstring GetSDDLForVista(WinSandbox::ObjectSecurityType type) {
153   return TestableWinSandbox::GetSDDL(
154       type, kDummyUserSID, kDummyGroupSID, false);
155 }
156 
GetSDDLForWin8(WinSandbox::ObjectSecurityType type)157 std::wstring GetSDDLForWin8(WinSandbox::ObjectSecurityType type) {
158   return TestableWinSandbox::GetSDDL(
159       type, kDummyUserSID, kDummyGroupSID, true);
160 }
161 
TEST(WinSandboxTest,GetSDDLForSharablePipe)162 TEST(WinSandboxTest, GetSDDLForSharablePipe) {
163   EXPECT_EQ(
164       L"O:S-8"
165       L"G:S-9"
166       L"D:(A;;;;;OW)(D;;GA;;;NU)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)"
167       L"S:(ML;;NX;;;LW)",
168       GetSDDLForVista(WinSandbox::kSharablePipe));
169   EXPECT_EQ(
170       L"O:S-8"
171       L"G:S-9"
172       L"D:(A;;;;;OW)(D;;GA;;;NU)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AC)"
173       L"(A;;GA;;;S-8)"
174       L"S:(ML;;NX;;;LW)",
175       GetSDDLForWin8(WinSandbox::kSharablePipe));
176 }
177 
TEST(WinSandboxTest,GetSDDLForLooseSharablePipe)178 TEST(WinSandboxTest, GetSDDLForLooseSharablePipe) {
179   EXPECT_EQ(
180       L"O:S-8"
181       L"G:S-9"
182       L"D:(A;;;;;OW)(D;;GA;;;NU)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)"
183       L"(A;;GA;;;RC)"
184       L"S:(ML;;NX;;;LW)",
185       GetSDDLForVista(WinSandbox::kLooseSharablePipe));
186   EXPECT_EQ(
187       L"O:S-8"
188       L"G:S-9"
189       L"D:(A;;;;;OW)(D;;GA;;;NU)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;AC)"
190       L"(A;;GA;;;S-8)(A;;GA;;;RC)"
191       L"S:(ML;;NX;;;LW)",
192       GetSDDLForWin8(WinSandbox::kLooseSharablePipe));
193 }
194 
TEST(WinSandboxTest,GetSDDLForSharableEvent)195 TEST(WinSandboxTest, GetSDDLForSharableEvent) {
196   EXPECT_EQ(
197       L"O:S-8"
198       L"G:S-9"
199       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)(A;;GX;;;RC)"
200       L"S:(ML;;NX;;;LW)",
201       GetSDDLForVista(WinSandbox::kSharableEvent));
202   EXPECT_EQ(
203       L"O:S-8"
204       L"G:S-9"
205       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GX;;;AC)(A;;GA;;;S-8)"
206       L"(A;;GX;;;RC)"
207       L"S:(ML;;NX;;;LW)",
208       GetSDDLForWin8(WinSandbox::kSharableEvent));
209 }
210 
TEST(WinSandboxTest,GetSDDLForSharableMutex)211 TEST(WinSandboxTest, GetSDDLForSharableMutex) {
212   EXPECT_EQ(
213       L"O:S-8"
214       L"G:S-9"
215       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)(A;;GX;;;RC)"
216       L"S:(ML;;NX;;;LW)",
217       GetSDDLForVista(WinSandbox::kSharableMutex));
218   EXPECT_EQ(
219       L"O:S-8"
220       L"G:S-9"
221       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GX;;;AC)(A;;GA;;;S-8)"
222       L"(A;;GX;;;RC)"
223       L"S:(ML;;NX;;;LW)",
224       GetSDDLForWin8(WinSandbox::kSharableMutex));
225 }
226 
TEST(WinSandboxTest,GetSDDLForSharableFileForRead)227 TEST(WinSandboxTest, GetSDDLForSharableFileForRead) {
228   EXPECT_EQ(
229       L"O:S-8"
230       L"G:S-9"
231       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)(A;;GR;;;RC)"
232       L"S:(ML;;NWNX;;;LW)",
233       GetSDDLForVista(WinSandbox::kSharableFileForRead));
234   EXPECT_EQ(
235       L"O:S-8"
236       L"G:S-9"
237       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;AC)(A;;GA;;;S-8)"
238       L"(A;;GR;;;RC)"
239       L"S:(ML;;NWNX;;;LW)",
240       GetSDDLForWin8(WinSandbox::kSharableFileForRead));
241 }
242 
TEST(WinSandboxTest,GetSDDLForIPCServerProcess)243 TEST(WinSandboxTest, GetSDDLForIPCServerProcess) {
244   EXPECT_EQ(
245       L"O:S-8"
246       L"G:S-9"
247       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)(A;;0x1000;;;RC)",
248       GetSDDLForVista(WinSandbox::kIPCServerProcess));
249   EXPECT_EQ(
250       L"O:S-8"
251       L"G:S-9"
252       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;0x1000;;;AC)(A;;GA;;;S-8)"
253       L"(A;;0x1000;;;RC)",
254       GetSDDLForWin8(WinSandbox::kIPCServerProcess));
255 }
256 
TEST(WinSandboxTest,GetSDDLForPrivateObject)257 TEST(WinSandboxTest, GetSDDLForPrivateObject) {
258   EXPECT_EQ(
259       L"O:S-8"
260       L"G:S-9"
261       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)",
262       GetSDDLForVista(WinSandbox::kPrivateObject));
263   EXPECT_EQ(
264       L"O:S-8"
265       L"G:S-9"
266       L"D:(A;;;;;OW)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;S-8)",
267       GetSDDLForWin8(WinSandbox::kPrivateObject));
268 }
269 
270 }  // namespace
271 }  // namespace mozc
272