15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shlobj.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/registry_policy.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_policy.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_factory.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/nt_internals.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/win_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/tests/common/controller.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const DWORD kAllowedRegFlags = KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      KEY_NOTIFY | KEY_READ | GENERIC_READ |
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      GENERIC_EXECUTE | READ_CONTROL;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#define BINDNTDLL(name) \
236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  name ## Function name = reinterpret_cast<name ## Function>( \
246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsKeyOpenForRead(HKEY handle) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BINDNTDLL(NtQueryObject);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OBJECT_BASIC_INFORMATION info = {0};
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS status = NtQueryObject(handle, ObjectBasicInformation, &info,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  sizeof(info), NULL);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!NT_SUCCESS(status))
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if ((info.GrantedAccess & (~kAllowedRegFlags)) != 0)
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return false;
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return true;
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace sandbox {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SBOX_TESTS_COMMAND int Reg_OpenKey(int argc, wchar_t **argv) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (argc != 4)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REGSAM desired_access = 0;
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ULONG options = 0;
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (wcscmp(argv[1], L"read") == 0) {
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    desired_access = KEY_READ;
536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  } else if (wcscmp(argv[1], L"write") == 0) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    desired_access = KEY_ALL_ACCESS;
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (wcscmp(argv[1], L"link") == 0) {
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    options = REG_OPTION_CREATE_LINK;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    desired_access = KEY_ALL_ACCESS;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    desired_access = MAXIMUM_ALLOWED;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HKEY root = GetReservedKeyFromName(argv[2]);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HKEY key;
646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  LRESULT result = 0;
656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (wcscmp(argv[0], L"create") == 0)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result = ::RegCreateKeyEx(root, argv[3], 0, NULL, options, desired_access,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              NULL, &key, NULL);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    result = ::RegOpenKeyEx(root, argv[3], 0, desired_access, &key);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ERROR_SUCCESS == result) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (MAXIMUM_ALLOWED == desired_access) {
746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (!IsKeyOpenForRead(key)) {
756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        ::RegCloseKey(key);
766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        return SBOX_TEST_FAILED;
776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ::RegCloseKey(key);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return SBOX_TEST_SUCCEEDED;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (ERROR_ACCESS_DENIED == result) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return SBOX_TEST_DENIED;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SBOX_TEST_FAILED;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(RegistryPolicyTest, TestKeyAnyAccess) {
896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  TestRunner runner;
906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                             TargetPolicy::REG_ALLOW_READONLY,
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                             L"HKEY_LOCAL_MACHINE"));
936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             TargetPolicy::REG_ALLOW_ANY,
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             L"HKEY_LOCAL_MACHINE\\Software\\Microsoft"));
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tests read access on key allowed for read-write.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft"));
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft"));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (::IsUserAnAdmin()) {
1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Tests write access on key allowed for read-write.
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        L"Reg_OpenKey create write HKEY_LOCAL_MACHINE software\\microsoft"));
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        L"Reg_OpenKey open write HKEY_LOCAL_MACHINE software\\microsoft"));
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Tests subdirectory access on keys where we don't have subdirectory acess.
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create read "
1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      L"HKEY_LOCAL_MACHINE software\\microsoft\\Windows"));
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey open read "
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      L"HKEY_LOCAL_MACHINE software\\microsoft\\windows"));
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Tests to see if we can create keys where we dont have subdirectory access.
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // This is denied.
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create write "
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      L"HKEY_LOCAL_MACHINE software\\Microsoft\\google_unit_tests"));
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Microsoft\\google_unit_tests");
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Tests if we need to handle differently the "\\" at the end.
1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // This is denied. We need to add both rules.
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft\\"));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
134      L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft\\"));
135}
136
137TEST(RegistryPolicyTest, TestKeyNoAccess) {
138  TestRunner runner;
139
140  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
141                             TargetPolicy::REG_ALLOW_READONLY,
142                             L"HKEY_LOCAL_MACHINE"));
143
144  // Tests read access where we don't have access at all.
145  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
146      L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software"));
147
148  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
149      L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software"));
150}
151
152TEST(RegistryPolicyTest, TestKeyReadOnlyAccess) {
153  TestRunner runner;
154
155  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
156                             TargetPolicy::REG_ALLOW_READONLY,
157                             L"HKEY_LOCAL_MACHINE"));
158
159  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
160                             TargetPolicy::REG_ALLOW_READONLY,
161                             L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
162
163  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
164                             TargetPolicy::REG_ALLOW_READONLY,
165                             L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
166
167  // Tests subdirectory acess on keys where we have subdirectory acess.
168  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create read "
169      L"HKEY_LOCAL_MACHINE software\\Policies\\microsoft"));
170
171  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey open read "
172      L"HKEY_LOCAL_MACHINE software\\Policies\\microsoft"));
173
174  // Tests to see if we can create keys where we have subdirectory access.
175  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create write "
176      L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
177
178  RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
179}
180
181TEST(RegistryPolicyTest, TestKeyAllAccessSubDir) {
182  TestRunner runner;
183
184  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
185                             TargetPolicy::REG_ALLOW_READONLY,
186                             L"HKEY_LOCAL_MACHINE"));
187
188  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
189                             TargetPolicy::REG_ALLOW_ANY,
190                             L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
191
192  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
193                             TargetPolicy::REG_ALLOW_ANY,
194                             L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
195
196  if (::IsUserAnAdmin()) {
197    // Tests to see if we can create keys where we have subdirectory access.
198    EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create write "
199        L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
200
201    RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
202  }
203}
204
205TEST(RegistryPolicyTest, TestKeyCreateLink) {
206  TestRunner runner;
207
208  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
209                             TargetPolicy::REG_ALLOW_READONLY,
210                             L"HKEY_LOCAL_MACHINE"));
211
212  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
213                             TargetPolicy::REG_ALLOW_ANY,
214                             L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
215
216  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
217                             TargetPolicy::REG_ALLOW_ANY,
218                             L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
219
220  // Tests to see if we can create a registry link key.
221  // NOTE: In theory here we should make sure to check for SBOX_TEST_DENIED
222  // instead of !SBOX_TEST_SUCCEEDED, but unfortunately the result is not
223  // access denied. Internally RegCreateKeyEx (At least on Vista 64) tries to
224  // create the link, and we return successfully access denied, then, it
225  // decides to try to break the path in multiple chunks, and create the links
226  // one by one. In this scenario, it tries to create "HKLM\Software" as a
227  // link key, which obviously fail with STATUS_OBJECT_NAME_COLLISION, and
228  // this is what is returned to the user.
229  EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create link "
230      L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests"));
231
232  // In case our code fails, and the call works, we need to delete the new
233  // link. There is no api for this, so we need to use the NT call.
234  HKEY key = NULL;
235  LRESULT result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
236                                  L"software\\Policies\\google_unit_tests",
237                                  REG_OPTION_OPEN_LINK, MAXIMUM_ALLOWED,
238                                  &key);
239
240  if (!result) {
241    HMODULE ntdll = GetModuleHandle(L"ntdll.dll");
242    NtDeleteKeyFunction NtDeleteKey =
243        reinterpret_cast<NtDeleteKeyFunction>(GetProcAddress(ntdll,
244                                                             "NtDeleteKey"));
245    NtDeleteKey(key);
246  }
247}
248
249TEST(RegistryPolicyTest, TestKeyReadOnlyHKCU) {
250  TestRunner runner;
251  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
252                             TargetPolicy::REG_ALLOW_READONLY,
253                             L"HKEY_CURRENT_USER"));
254
255  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
256                             TargetPolicy::REG_ALLOW_READONLY,
257                             L"HKEY_CURRENT_USER\\Software"));
258
259  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
260                             TargetPolicy::REG_ALLOW_READONLY,
261                             L"HKEY_USERS\\.default"));
262
263  EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
264                             TargetPolicy::REG_ALLOW_READONLY,
265                             L"HKEY_USERS\\.default\\software"));
266
267  // Tests read access where we only have read-only access.
268  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
269      L"Reg_OpenKey create read HKEY_CURRENT_USER software"));
270
271  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
272      L"Reg_OpenKey open read HKEY_CURRENT_USER software"));
273
274  // Tests write access where we only have read-only acess.
275  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
276      L"Reg_OpenKey create write HKEY_CURRENT_USER software"));
277
278  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
279      L"Reg_OpenKey open write HKEY_CURRENT_USER software"));
280
281  // Tests maximum allowed access where we only have read-only access.
282  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
283      L"Reg_OpenKey create maximum_allowed HKEY_CURRENT_USER software"));
284
285  EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
286      L"Reg_OpenKey open maximum_allowed HKEY_CURRENT_USER software"));
287}
288
289}  // namespace sandbox
290