diff options
author | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-22 21:29:21 +0000 |
---|---|---|
committer | nsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-22 21:29:21 +0000 |
commit | afe0b22a98f445bbaa071ae393a7dd2ff0cad96d (patch) | |
tree | 8bdeaea4779e0fc0869ceeab832f202c66abfcc2 /sandbox/src | |
parent | d4d412afb596aac85bf3bceef852dcb6954bcc92 (diff) | |
download | chromium_src-afe0b22a98f445bbaa071ae393a7dd2ff0cad96d.zip chromium_src-afe0b22a98f445bbaa071ae393a7dd2ff0cad96d.tar.gz chromium_src-afe0b22a98f445bbaa071ae393a7dd2ff0cad96d.tar.bz2 |
Make sure we can't create reg links from the sandbox.
BUG=28805
Review URL: http://codereview.chromium.org/555041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36895 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src')
-rw-r--r-- | sandbox/src/nt_internals.h | 3 | ||||
-rw-r--r-- | sandbox/src/registry_interception.cc | 4 | ||||
-rw-r--r-- | sandbox/src/registry_policy.cc | 6 | ||||
-rw-r--r-- | sandbox/src/registry_policy_test.cc | 61 |
4 files changed, 68 insertions, 6 deletions
diff --git a/sandbox/src/nt_internals.h b/sandbox/src/nt_internals.h index 1e664d7..16a3abc 100644 --- a/sandbox/src/nt_internals.h +++ b/sandbox/src/nt_internals.h @@ -360,6 +360,9 @@ typedef NTSTATUS (WINAPI *NtOpenKeyExFunction)( IN POBJECT_ATTRIBUTES ObjectAttributes, IN DWORD open_options); +typedef NTSTATUS (WINAPI *NtDeleteKeyFunction)( + IN HANDLE KeyHandle); + // ----------------------------------------------------------------------- // Memory diff --git a/sandbox/src/registry_interception.cc b/sandbox/src/registry_interception.cc index aaeab92..e7421ce 100644 --- a/sandbox/src/registry_interception.cc +++ b/sandbox/src/registry_interception.cc @@ -40,6 +40,10 @@ NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey, if (class_name && class_name->Buffer && class_name->Length) break; + // We don't support creating link keys, volatile keys and backup/restore. + if (create_options) + break; + void* memory = GetGlobalIPCMemory(); if (NULL == memory) break; diff --git a/sandbox/src/registry_policy.cc b/sandbox/src/registry_policy.cc index 267e332..2943033 100644 --- a/sandbox/src/registry_policy.cc +++ b/sandbox/src/registry_policy.cc @@ -185,6 +185,12 @@ bool RegistryPolicy::CreateKeyAction(EvalResult eval_result, return false; } + // We don't support creating link keys, volatile keys or backup/restore. + if (create_options) { + *nt_status = STATUS_ACCESS_DENIED; + return false; + } + UNICODE_STRING uni_name = {0}; OBJECT_ATTRIBUTES obj_attributes = {0}; InitObjectAttribs(key, attributes, root_directory, &obj_attributes, diff --git a/sandbox/src/registry_policy_test.cc b/sandbox/src/registry_policy_test.cc index cbc1961..1cc9b89 100644 --- a/sandbox/src/registry_policy_test.cc +++ b/sandbox/src/registry_policy_test.cc @@ -46,21 +46,26 @@ SBOX_TESTS_COMMAND int Reg_OpenKey(int argc, wchar_t **argv) { if (argc != 4) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; - REGSAM desired_access; - if (wcscmp(argv[1], L"read") == 0) + REGSAM desired_access = 0; + ULONG options = 0; + if (wcscmp(argv[1], L"read") == 0) { desired_access = KEY_READ; - else if (wcscmp(argv[1], L"write") == 0) + } else if (wcscmp(argv[1], L"write") == 0) { desired_access = KEY_ALL_ACCESS; - else + } else if (wcscmp(argv[1], L"link") == 0) { + options = REG_OPTION_CREATE_LINK; + desired_access = KEY_ALL_ACCESS; + } else { desired_access = MAXIMUM_ALLOWED; + } HKEY root = GetReservedKeyFromName(argv[2]); HKEY key; LRESULT result = 0; if (wcscmp(argv[0], L"create") == 0) - result = ::RegCreateKeyEx(root, argv[3], 0, NULL, 0, desired_access, NULL, - &key, NULL); + result = ::RegCreateKeyEx(root, argv[3], 0, NULL, options, desired_access, + NULL, &key, NULL); else result = ::RegOpenKeyEx(root, argv[3], 0, desired_access, &key); @@ -195,6 +200,50 @@ TEST(RegistryPolicyTest, TestKeyAllAccessSubDir) { } } +TEST(RegistryPolicyTest, TestKeyCreateLink) { + TestRunner runner; + + EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY, + TargetPolicy::REG_ALLOW_READONLY, + L"HKEY_LOCAL_MACHINE")); + + EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY, + TargetPolicy::REG_ALLOW_ANY, + L"HKEY_LOCAL_MACHINE\\Software\\Policies")); + + EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY, + TargetPolicy::REG_ALLOW_ANY, + L"HKEY_LOCAL_MACHINE\\Software\\Policies\\*")); + + // Tests to see if we can create a registry link key. + // NOTE: In theory here we should make sure to check for SBOX_TEST_DENIED + // instead of !SBOX_TEST_SUCCEEDED, but unfortunately the result is not + // access denied. Internally RegCreateKeyEx (At least on Vista 64) tries to + // create the link, and we return successfully access denied, then, it + // decides to try to break the path in multiple chunks, and create the links + // one by one. In this scenario, it tries to create "HKLM\Software" as a + // link key, which obviously fail with STATUS_OBJECT_NAME_COLLISION, and + // this is what is returned to the user. + EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Reg_OpenKey create link " + L"HKEY_LOCAL_MACHINE software\\Policies\\google_unit_tests")); + + // In case our code fails, and the call works, we need to delete the new + // link. There is no api for this, so we need to use the NT call. + HKEY key = NULL; + LRESULT result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, + L"software\\Policies\\google_unit_tests", + REG_OPTION_OPEN_LINK, MAXIMUM_ALLOWED, + &key); + + if (!result) { + HMODULE ntdll = GetModuleHandle(L"ntdll.dll"); + NtDeleteKeyFunction NtDeleteKey = + reinterpret_cast<NtDeleteKeyFunction>(GetProcAddress(ntdll, + "NtDeleteKey")); + NtDeleteKey(key); + } +} + TEST(RegistryPolicyTest, TestKeyReadOnlyHKCU) { TestRunner runner; EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_REGISTRY, |