security/sandbox/win/src/registry_policy_test.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     5 #include <shlobj.h>
     7 #include "testing/gtest/include/gtest/gtest.h"
     8 #include "sandbox/win/src/registry_policy.h"
     9 #include "sandbox/win/src/sandbox.h"
    10 #include "sandbox/win/src/sandbox_policy.h"
    11 #include "sandbox/win/src/sandbox_factory.h"
    12 #include "sandbox/win/src/nt_internals.h"
    13 #include "sandbox/win/src/win_utils.h"
    14 #include "sandbox/win/tests/common/controller.h"
    16 namespace {
    18 static const DWORD kAllowedRegFlags = KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS |
    19                                       KEY_NOTIFY | KEY_READ | GENERIC_READ |
    20                                       GENERIC_EXECUTE | READ_CONTROL;
    22 #define BINDNTDLL(name) \
    23   name ## Function name = reinterpret_cast<name ## Function>( \
    24     ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
    26 bool IsKeyOpenForRead(HKEY handle) {
    27   BINDNTDLL(NtQueryObject);
    29   OBJECT_BASIC_INFORMATION info = {0};
    30   NTSTATUS status = NtQueryObject(handle, ObjectBasicInformation, &info,
    31                                   sizeof(info), NULL);
    33   if (!NT_SUCCESS(status))
    34     return false;
    36   if ((info.GrantedAccess & (~kAllowedRegFlags)) != 0)
    37     return false;
    38   return true;
    39 }
    41 }
    43 namespace sandbox {
    45 SBOX_TESTS_COMMAND int Reg_OpenKey(int argc, wchar_t **argv) {
    46   if (argc != 4)
    47     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    49   REGSAM desired_access = 0;
    50   ULONG options = 0;
    51   if (wcscmp(argv[1], L"read") == 0) {
    52     desired_access = KEY_READ;
    53   } else if (wcscmp(argv[1], L"write") == 0) {
    54     desired_access = KEY_ALL_ACCESS;
    55   } else if (wcscmp(argv[1], L"link") == 0) {
    56     options = REG_OPTION_CREATE_LINK;
    57     desired_access = KEY_ALL_ACCESS;
    58   } else {
    59     desired_access = MAXIMUM_ALLOWED;
    60   }
    62   HKEY root = GetReservedKeyFromName(argv[2]);
    63   HKEY key;
    64   LRESULT result = 0;
    66   if (wcscmp(argv[0], L"create") == 0)
    67     result = ::RegCreateKeyEx(root, argv[3], 0, NULL, options, desired_access,
    68                               NULL, &key, NULL);
    69   else
    70     result = ::RegOpenKeyEx(root, argv[3], 0, desired_access, &key);
    72   if (ERROR_SUCCESS == result) {
    73     if (MAXIMUM_ALLOWED == desired_access) {
    74       if (!IsKeyOpenForRead(key)) {
    75         ::RegCloseKey(key);
    76         return SBOX_TEST_FAILED;
    77       }
    78     }
    79     ::RegCloseKey(key);
    80     return SBOX_TEST_SUCCEEDED;
    81   } else if (ERROR_ACCESS_DENIED == result) {
    82     return SBOX_TEST_DENIED;
    83   }
    85   return SBOX_TEST_FAILED;
    86 }
    88 TEST(RegistryPolicyTest, TestKeyAnyAccess) {
    89   TestRunner runner;
    90   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
    91                              TargetPolicy::REG_ALLOW_READONLY,
    92                              L"HKEY_LOCAL_MACHINE"));
    94   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
    95                              TargetPolicy::REG_ALLOW_ANY,
    96                              L"HKEY_LOCAL_MACHINE\\Software\\Microsoft"));
    98   // Tests read access on key allowed for read-write.
    99   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   100       L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft"));
   102   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   103       L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft"));
   105   if (::IsUserAnAdmin()) {
   106     // Tests write access on key allowed for read-write.
   107     EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   108         L"Reg_OpenKey create write HKEY_LOCAL_MACHINE software\\microsoft"));
   110     EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   111         L"Reg_OpenKey open write HKEY_LOCAL_MACHINE software\\microsoft"));
   112   }
   114   // Tests subdirectory access on keys where we don't have subdirectory acess.
   115   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create read "
   116       L"HKEY_LOCAL_MACHINE software\\microsoft\\Windows"));
   118   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey open read "
   119       L"HKEY_LOCAL_MACHINE software\\microsoft\\windows"));
   121   // Tests to see if we can create keys where we dont have subdirectory access.
   122   // This is denied.
   123   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Reg_OpenKey create write "
   124       L"HKEY_LOCAL_MACHINE software\\Microsoft\\google_unit_tests"));
   126   RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Microsoft\\google_unit_tests");
   128   // Tests if we need to handle differently the "\\" at the end.
   129   // This is denied. We need to add both rules.
   130   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
   131       L"Reg_OpenKey create read HKEY_LOCAL_MACHINE software\\microsoft\\"));
   133   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
   134       L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software\\microsoft\\"));
   135 }
   137 TEST(RegistryPolicyTest, TestKeyNoAccess) {
   138   TestRunner runner;
   140   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   141                              TargetPolicy::REG_ALLOW_READONLY,
   142                              L"HKEY_LOCAL_MACHINE"));
   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"));
   148   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
   149       L"Reg_OpenKey open read HKEY_LOCAL_MACHINE software"));
   150 }
   152 TEST(RegistryPolicyTest, TestKeyReadOnlyAccess) {
   153   TestRunner runner;
   155   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   156                              TargetPolicy::REG_ALLOW_READONLY,
   157                              L"HKEY_LOCAL_MACHINE"));
   159   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   160                              TargetPolicy::REG_ALLOW_READONLY,
   161                              L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
   163   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   164                              TargetPolicy::REG_ALLOW_READONLY,
   165                              L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
   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"));
   171   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey open read "
   172       L"HKEY_LOCAL_MACHINE software\\Policies\\microsoft"));
   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"));
   178   RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
   179 }
   181 TEST(RegistryPolicyTest, TestKeyAllAccessSubDir) {
   182   TestRunner runner;
   184   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   185                              TargetPolicy::REG_ALLOW_READONLY,
   186                              L"HKEY_LOCAL_MACHINE"));
   188   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   189                              TargetPolicy::REG_ALLOW_ANY,
   190                              L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
   192   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   193                              TargetPolicy::REG_ALLOW_ANY,
   194                              L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
   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"));
   201     RegDeleteKey(HKEY_LOCAL_MACHINE, L"software\\Policies\\google_unit_tests");
   202   }
   203 }
   205 TEST(RegistryPolicyTest, TestKeyCreateLink) {
   206   TestRunner runner;
   208   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   209                              TargetPolicy::REG_ALLOW_READONLY,
   210                              L"HKEY_LOCAL_MACHINE"));
   212   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   213                              TargetPolicy::REG_ALLOW_ANY,
   214                              L"HKEY_LOCAL_MACHINE\\Software\\Policies"));
   216   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   217                              TargetPolicy::REG_ALLOW_ANY,
   218                              L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*"));
   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"));
   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);
   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 }
   249 TEST(RegistryPolicyTest, TestKeyReadOnlyHKCU) {
   250   TestRunner runner;
   251   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   252                              TargetPolicy::REG_ALLOW_READONLY,
   253                              L"HKEY_CURRENT_USER"));
   255   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   256                              TargetPolicy::REG_ALLOW_READONLY,
   257                              L"HKEY_CURRENT_USER\\Software"));
   259   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   260                              TargetPolicy::REG_ALLOW_READONLY,
   261                              L"HKEY_USERS\\.default"));
   263   EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY,
   264                              TargetPolicy::REG_ALLOW_READONLY,
   265                              L"HKEY_USERS\\.default\\software"));
   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"));
   271   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   272       L"Reg_OpenKey open read HKEY_CURRENT_USER software"));
   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"));
   278   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(
   279       L"Reg_OpenKey open write HKEY_CURRENT_USER software"));
   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"));
   285   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(
   286       L"Reg_OpenKey open maximum_allowed HKEY_CURRENT_USER software"));
   287 }
   289 }  // namespace sandbox

mercurial