diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-07 03:10:12 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-07 03:10:12 +0000 |
commit | a7cab943cd84df541a4f290a431f39942f3934bf (patch) | |
tree | ae28a35b76b2d6676b0bcb1115ddfd8b51c03117 /sandbox/src | |
parent | b78804c8b2abe1ea162383795e612af1a09e273f (diff) | |
download | chromium_src-a7cab943cd84df541a4f290a431f39942f3934bf.zip chromium_src-a7cab943cd84df541a4f290a431f39942f3934bf.tar.gz chromium_src-a7cab943cd84df541a4f290a431f39942f3934bf.tar.bz2 |
Allow native (nt-style) paths to be used for sandbox policy specification
1- bypass fixup when adding the path into the policy
2- make SameObject() do case-insensitive perfect match
BUG=50774
TEST= unit test included
Review URL: http://codereview.chromium.org/3092014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55329 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src')
-rw-r--r-- | sandbox/src/file_policy_test.cc | 24 | ||||
-rw-r--r-- | sandbox/src/filesystem_policy.cc | 31 | ||||
-rw-r--r-- | sandbox/src/win_utils.cc | 14 | ||||
-rw-r--r-- | sandbox/src/win_utils.h | 9 |
4 files changed, 61 insertions, 17 deletions
diff --git a/sandbox/src/file_policy_test.cc b/sandbox/src/file_policy_test.cc index 01a8383..2abf6e2 100644 --- a/sandbox/src/file_policy_test.cc +++ b/sandbox/src/file_policy_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <algorithm> +#include <cctype> #include <windows.h> #include <winioctl.h> @@ -10,6 +12,7 @@ #include "sandbox/src/sandbox.h" #include "sandbox/src/sandbox_factory.h" #include "sandbox/src/sandbox_policy.h" +#include "sandbox/src/win_utils.h" #include "sandbox/tests/common/controller.h" #include "sandbox/tests/common/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,7 +92,10 @@ SBOX_TESTS_COMMAND int File_CreateSys32(int argc, wchar_t **argv) { if (argc != 1) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; - std::wstring file = MakePathToSys(argv[0], true); + std::wstring file(argv[0]); + if (0 != _wcsnicmp(file.c_str(), kNTObjManPrefix, kNTObjManPrefixLen)) + file = MakePathToSys(argv[0], true); + UNICODE_STRING object_name; RtlInitUnicodeString(&object_name, file.c_str()); @@ -256,6 +262,22 @@ TEST(FilePolicyTest, AllowNtCreateCalc) { EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe")); } +TEST(FilePolicyTest, AllowNtCreateWithNativePath) { + std::wstring calc = MakePathToSys(L"calc.exe", false); + std::wstring nt_path; + ASSERT_TRUE(GetNtPathFromWin32Path(calc, &nt_path)); + TestRunner runner; + runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY, nt_path.c_str()); + + wchar_t buff[MAX_PATH]; + ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str()); + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff)); + + std::transform(nt_path.begin(), nt_path.end(), nt_path.begin(), std::tolower); + ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str()); + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff)); +} + TEST(FilePolicyTest, AllowReadOnly) { TestRunner runner; diff --git a/sandbox/src/filesystem_policy.cc b/sandbox/src/filesystem_policy.cc index a703188..2a15555 100644 --- a/sandbox/src/filesystem_policy.cc +++ b/sandbox/src/filesystem_policy.cc @@ -67,20 +67,23 @@ bool FileSystemPolicy::GenerateRules(const wchar_t* name, return false; } - // TODO(cpu) bug 32224: This prefix add is a hack because we don't have the - // infrastructure to normalize names. In any case we need to escape the - // question marks. - if (!PreProcessName(mod_name, &mod_name)) { - // The path to be added might contain a reparse point. - NOTREACHED(); - return false; - } - - if (0 != mod_name.compare(0, kNTPrefixLen, kNTPrefix)) { - // TODO(nsylvain): Find a better way to do name resolution. Right now we - // take the name and we expand it. - mod_name.insert(0, L"\\/?/?\\"); - name = mod_name.c_str(); + // Don't do any pre-processing if the name starts like the the native + // object manager style. + if (0 != _wcsnicmp(mod_name.c_str(), kNTObjManPrefix, kNTObjManPrefixLen)) { + // TODO(cpu) bug 32224: This prefix add is a hack because we don't have the + // infrastructure to normalize names. In any case we need to escape the + // question marks. + if (!PreProcessName(mod_name, &mod_name)) { + // The path to be added might contain a reparse point. + NOTREACHED(); + return false; + } + if (0 != mod_name.compare(0, kNTPrefixLen, kNTPrefix)) { + // TODO(nsylvain): Find a better way to do name resolution. Right now we + // take the name and we expand it. + mod_name.insert(0, L"\\/?/?\\"); + name = mod_name.c_str(); + } } EvalResult result = ASK_BROKER; diff --git a/sandbox/src/win_utils.cc b/sandbox/src/win_utils.cc index 8be9ce4..7a95b32 100644 --- a/sandbox/src/win_utils.cc +++ b/sandbox/src/win_utils.cc @@ -139,7 +139,8 @@ bool SameObject(HANDLE handle, const wchar_t* full_path) { if (path[path.length() - 1] == kBackslash) path = path.substr(0, path.length() - 1); - if (0 == actual_path.compare(full_path)) + // Perfect match (case-insesitive check). + if (0 == _wcsicmp(actual_path.c_str(), path.c_str())) return true; // Look for the drive letter. @@ -265,6 +266,17 @@ bool GetPathFromHandle(HANDLE handle, std::wstring* path) { return true; } +bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) { + HANDLE file = ::CreateFileW(path.c_str(), 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (file == INVALID_HANDLE_VALUE) + return false; + bool rv = GetPathFromHandle(file, nt_path); + ::CloseHandle(file); + return rv; +} + bool WriteProtectedChildMemory(HANDLE child_process, void* address, const void* buffer, size_t length) { // First, remove the protections. diff --git a/sandbox/src/win_utils.h b/sandbox/src/win_utils.h index 8bc44b7..a80bb81 100644 --- a/sandbox/src/win_utils.h +++ b/sandbox/src/win_utils.h @@ -15,6 +15,9 @@ namespace sandbox { const wchar_t kNTPrefix[] = L"\\??\\"; const size_t kNTPrefixLen = arraysize(kNTPrefix) - 1; +const wchar_t kNTObjManPrefix[] = L"\\Device\\"; +const size_t kNTObjManPrefixLen = arraysize(kNTObjManPrefix) - 1; + // Automatically acquires and releases a lock when the object is // is destroyed. class AutoLock { @@ -74,9 +77,13 @@ DWORD IsReparsePoint(const std::wstring& full_path, bool* result); // Returns true if the handle corresponds to the object pointed by this path. bool SameObject(HANDLE handle, const wchar_t* full_path); -// Resolves a handle to a path. Returns true if the handle can be resolved. +// Resolves a handle to an nt path. Returns true if the handle can be resolved. bool GetPathFromHandle(HANDLE handle, std::wstring* path); +// Resolves a win32 path to an nt path using GetPathFromHandle. The path must +// exist. Returs true if the translation was succesful. +bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path); + // Translates a reserved key name to its handle. // For example "HKEY_LOCAL_MACHINE" returns HKEY_LOCAL_MACHINE. // Returns NULL if the name does not represent any reserved key name. |