diff options
author | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-04 03:12:21 +0000 |
---|---|---|
committer | robertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-04 03:12:21 +0000 |
commit | 1fa91d332a52fc3d11eff61b95a270686af8e587 (patch) | |
tree | b790dc02750d9144530e46ee1f6e8d28c409c315 /sandbox | |
parent | 6e6a9edf41e9cf09c6d3bb580d1398f3161c8f47 (diff) | |
download | chromium_src-1fa91d332a52fc3d11eff61b95a270686af8e587.zip chromium_src-1fa91d332a52fc3d11eff61b95a270686af8e587.tar.gz chromium_src-1fa91d332a52fc3d11eff61b95a270686af8e587.tar.bz2 |
Restructure sandbox code to reduce dependencies pulled in by intercept code.
BUG=322710
TEST=NONE
Review URL: https://codereview.chromium.org/84063004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238538 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/win/sandbox_win.gypi | 1 | ||||
-rw-r--r-- | sandbox/win/src/nt_internals.h | 7 | ||||
-rw-r--r-- | sandbox/win/src/policy_broker.cc | 1 | ||||
-rw-r--r-- | sandbox/win/src/sandbox.cc | 2 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_globals.cc | 18 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_nt_types.h | 1 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_nt_util.cc | 12 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_nt_util.h | 3 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_utils.cc | 4 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_utils.h | 8 | ||||
-rw-r--r-- | sandbox/win/src/service_resolver.cc | 12 | ||||
-rw-r--r-- | sandbox/win/src/service_resolver.h | 3 | ||||
-rw-r--r-- | sandbox/win/src/service_resolver_64.cc | 16 | ||||
-rw-r--r-- | sandbox/win/src/service_resolver_unittest.cc | 41 | ||||
-rw-r--r-- | sandbox/win/src/win_utils.cc | 8 |
15 files changed, 101 insertions, 36 deletions
diff --git a/sandbox/win/sandbox_win.gypi b/sandbox/win/sandbox_win.gypi index 881a650..1fa8279 100644 --- a/sandbox/win/sandbox_win.gypi +++ b/sandbox/win/sandbox_win.gypi @@ -93,6 +93,7 @@ 'src/restricted_token.cc', 'src/restricted_token.h', 'src/sandbox_factory.h', + 'src/sandbox_globals.cc', 'src/sandbox_nt_types.h', 'src/sandbox_nt_util.cc', 'src/sandbox_nt_util.h', diff --git a/sandbox/win/src/nt_internals.h b/sandbox/win/src/nt_internals.h index 1423be4..e0c74ac 100644 --- a/sandbox/win/src/nt_internals.h +++ b/sandbox/win/src/nt_internals.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright 2013 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. @@ -601,6 +601,11 @@ typedef size_t (__cdecl *strlenFunction)( typedef size_t (__cdecl *wcslenFunction)( IN const wchar_t* _Str); +typedef void* (__cdecl *memcpyFunction)( + IN void* dest, + IN const void* src, + IN size_t count); + typedef NTSTATUS (WINAPI *RtlAnsiStringToUnicodeStringFunction)( IN OUT PUNICODE_STRING DestinationString, IN PANSI_STRING SourceString, diff --git a/sandbox/win/src/policy_broker.cc b/sandbox/win/src/policy_broker.cc index fbe4619..dc5e18c 100644 --- a/sandbox/win/src/policy_broker.cc +++ b/sandbox/win/src/policy_broker.cc @@ -73,6 +73,7 @@ bool SetupNtdllImports(TargetProcess *child) { INIT_GLOBAL_RTL(_strnicmp); INIT_GLOBAL_RTL(strlen); INIT_GLOBAL_RTL(wcslen); + INIT_GLOBAL_RTL(memcpy); #ifndef NDEBUG // Verify that the structure is fully initialized. diff --git a/sandbox/win/src/sandbox.cc b/sandbox/win/src/sandbox.cc index 9e4ab08..d26daa4 100644 --- a/sandbox/win/src/sandbox.cc +++ b/sandbox/win/src/sandbox.cc @@ -11,7 +11,7 @@ namespace sandbox { // The section for IPC and policy. -SANDBOX_INTERCEPT HANDLE g_shared_section = NULL; +SANDBOX_INTERCEPT HANDLE g_shared_section; static bool s_is_broker = false; diff --git a/sandbox/win/src/sandbox_globals.cc b/sandbox/win/src/sandbox_globals.cc new file mode 100644 index 0000000..b4ab523 --- /dev/null +++ b/sandbox/win/src/sandbox_globals.cc @@ -0,0 +1,18 @@ +// Copyright 2013 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 <windows.h> + +#include "sandbox/win/src/sandbox_nt_types.h" +#include "sandbox/win/src/sandbox_types.h" + +namespace sandbox { + +// The section for IPC and policy. +SANDBOX_INTERCEPT HANDLE g_shared_section = NULL; + +// This is the list of all imported symbols from ntdll.dll. +SANDBOX_INTERCEPT NtExports g_nt = {}; + +} // namespace sandbox diff --git a/sandbox/win/src/sandbox_nt_types.h b/sandbox/win/src/sandbox_nt_types.h index 1303ac2..46820cf 100644 --- a/sandbox/win/src/sandbox_nt_types.h +++ b/sandbox/win/src/sandbox_nt_types.h @@ -31,6 +31,7 @@ struct NtExports { _strnicmpFunction _strnicmp; strlenFunction strlen; wcslenFunction wcslen; + memcpyFunction memcpy; }; // This is the value used for the ntdll level allocator. diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc index 7131461..613d485 100644 --- a/sandbox/win/src/sandbox_nt_util.cc +++ b/sandbox/win/src/sandbox_nt_util.cc @@ -11,7 +11,7 @@ namespace sandbox { // This is the list of all imported symbols from ntdll.dll. -SANDBOX_INTERCEPT NtExports g_nt = { NULL }; +SANDBOX_INTERCEPT NtExports g_nt; } // namespace sandbox @@ -208,15 +208,7 @@ bool ValidParameter(void* buffer, size_t size, RequiredAccess intent) { NTSTATUS CopyData(void* destination, const void* source, size_t bytes) { NTSTATUS ret = STATUS_SUCCESS; __try { - if (SandboxFactory::GetTargetServices()->GetState()->InitCalled()) { - memcpy(destination, source, bytes); - } else { - const char* from = reinterpret_cast<const char*>(source); - char* to = reinterpret_cast<char*>(destination); - for (size_t i = 0; i < bytes; i++) { - to[i] = from[i]; - } - } + g_nt.memcpy(destination, source, bytes); } __except(EXCEPTION_EXECUTE_HANDLER) { ret = GetExceptionCode(); } diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h index e5d45fa..7c543f2 100644 --- a/sandbox/win/src/sandbox_nt_util.h +++ b/sandbox/win/src/sandbox_nt_util.h @@ -45,6 +45,8 @@ void __cdecl operator delete(void* memory, void* buffer, #define VERIFY_SUCCESS(action) (action) #endif +#define CHECK_NT(condition) { (condition) ? (void)0 : __debugbreak(); } + #define NOTREACHED_NT() DCHECK_NT(false) namespace sandbox { @@ -94,7 +96,6 @@ enum RequiredAccess { // write) bool ValidParameter(void* buffer, size_t size, RequiredAccess intent); - // Copies data from a user buffer to our buffer. Returns the operation status. NTSTATUS CopyData(void* destination, const void* source, size_t bytes); diff --git a/sandbox/win/src/sandbox_utils.cc b/sandbox/win/src/sandbox_utils.cc index f4511a4..9c561c9 100644 --- a/sandbox/win/src/sandbox_utils.cc +++ b/sandbox/win/src/sandbox_utils.cc @@ -28,11 +28,11 @@ void InitObjectAttribs(const std::wstring& name, if (!RtlInitUnicodeString) { HMODULE ntdll = ::GetModuleHandle(kNtdllName); RtlInitUnicodeString = reinterpret_cast<RtlInitUnicodeStringFunction>( - GetProcAddress(ntdll, "RtlInitUnicodeString")); + GetProcAddress(ntdll, "RtlInitUnicodeString")); DCHECK(RtlInitUnicodeString); } RtlInitUnicodeString(uni_name, name.c_str()); InitializeObjectAttributes(obj_attr, uni_name, attributes, root, NULL); } -}; // namespace sandbox +} // namespace sandbox diff --git a/sandbox/win/src/sandbox_utils.h b/sandbox/win/src/sandbox_utils.h index 78e76fb..9a90675 100644 --- a/sandbox/win/src/sandbox_utils.h +++ b/sandbox/win/src/sandbox_utils.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SANDBOX_SRC_SANDBOX_UTILS_H__ -#define SANDBOX_SRC_SANDBOX_UTILS_H__ +#ifndef SANDBOX_SRC_SANDBOX_UTILS_H_ +#define SANDBOX_SRC_SANDBOX_UTILS_H_ #include <windows.h> #include <string> @@ -22,6 +22,6 @@ void InitObjectAttribs(const std::wstring& name, OBJECT_ATTRIBUTES* obj_attr, UNICODE_STRING* uni_name); -}; // namespace sandbox +} // namespace sandbox -#endif // SANDBOX_SRC_SANDBOX_UTILS_H__ +#endif // SANDBOX_SRC_SANDBOX_UTILS_H_ diff --git a/sandbox/win/src/service_resolver.cc b/sandbox/win/src/service_resolver.cc index bae698c..92f21a7 100644 --- a/sandbox/win/src/service_resolver.cc +++ b/sandbox/win/src/service_resolver.cc @@ -1,11 +1,12 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright 2013 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 "sandbox/win/src/service_resolver.h" -#include "base/logging.h" #include "base/win/pe_image.h" +#include "sandbox/win/src/internal_types.h" +#include "sandbox/win/src/sandbox_nt_util.h" namespace sandbox { @@ -24,7 +25,6 @@ NTSTATUS ServiceResolverThunk::ResolveInterceptor( NTSTATUS ServiceResolverThunk::ResolveTarget(const void* module, const char* function_name, void** address) { - DCHECK(address); if (NULL == module) return STATUS_UNSUCCESSFUL; @@ -32,11 +32,15 @@ NTSTATUS ServiceResolverThunk::ResolveTarget(const void* module, *address = module_image.GetProcAddress(function_name); if (NULL == *address) { - NOTREACHED(); + NOTREACHED_NT(); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } +void ServiceResolverThunk::AllowLocalPatches() { + ntdll_base_ = ::GetModuleHandle(kNtdllName); +} + } // namespace sandbox diff --git a/sandbox/win/src/service_resolver.h b/sandbox/win/src/service_resolver.h index 3eb9e08..0089692 100644 --- a/sandbox/win/src/service_resolver.h +++ b/sandbox/win/src/service_resolver.h @@ -43,6 +43,9 @@ class ServiceResolverThunk : public ResolverThunk { // Implementation of Resolver::GetThunkSize. virtual size_t GetThunkSize() const; + // Call this to set up ntdll_base_ which will allow for local patches. + virtual void AllowLocalPatches(); + protected: // The unit test will use this member to allow local patch on a buffer. HMODULE ntdll_base_; diff --git a/sandbox/win/src/service_resolver_64.cc b/sandbox/win/src/service_resolver_64.cc index 32de53a..473ddbc 100644 --- a/sandbox/win/src/service_resolver_64.cc +++ b/sandbox/win/src/service_resolver_64.cc @@ -4,8 +4,8 @@ #include "sandbox/win/src/service_resolver.h" -#include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/win_utils.h" namespace { @@ -144,14 +144,14 @@ bool ServiceResolverThunk::IsFunctionAService(void* local_thunk) const { NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk, void* remote_thunk) { - ServiceFullThunk* full_local_thunk = reinterpret_cast<ServiceFullThunk*>( - local_thunk); - ServiceFullThunk* full_remote_thunk = reinterpret_cast<ServiceFullThunk*>( - remote_thunk); + ServiceFullThunk* full_local_thunk = + reinterpret_cast<ServiceFullThunk*>(local_thunk); + ServiceFullThunk* full_remote_thunk = + reinterpret_cast<ServiceFullThunk*>(remote_thunk); // Patch the original code. ServiceEntry local_service; - DCHECK_GE(GetInternalThunkSize(), sizeof(local_service)); + DCHECK_NT(GetInternalThunkSize() >= sizeof(local_service)); if (!SetInternalThunk(&local_service, sizeof(local_service), NULL, interceptor_)) return STATUS_UNSUCCESSFUL; @@ -181,12 +181,12 @@ NTSTATUS ServiceResolverThunk::PerformPatch(void* local_thunk, } bool Wow64ResolverThunk::IsFunctionAService(void* local_thunk) const { - NOTREACHED(); + NOTREACHED_NT(); return false; } bool Win2kResolverThunk::IsFunctionAService(void* local_thunk) const { - NOTREACHED(); + NOTREACHED_NT(); return false; } diff --git a/sandbox/win/src/service_resolver_unittest.cc b/sandbox/win/src/service_resolver_unittest.cc index 59105cc..b01fedf 100644 --- a/sandbox/win/src/service_resolver_unittest.cc +++ b/sandbox/win/src/service_resolver_unittest.cc @@ -44,7 +44,7 @@ class ResolverThunkTest : public T { EXPECT_EQ(STATUS_SUCCESS, ret); target_ = fake_target_; - ntdll_base_ = ::GetModuleHandle(L"ntdll.dll"); + return ret; }; @@ -108,6 +108,8 @@ NTSTATUS PatchNtdllWithResolver(const char* function, bool relaxed, scoped_ptr<char[]> thunk(new char[thunk_size]); size_t used; + resolver->AllowLocalPatches(); + NTSTATUS ret = resolver->Setup(ntdll_base, NULL, function, NULL, function_entry, thunk.get(), thunk_size, &used); @@ -224,4 +226,41 @@ TEST(ServiceResolverTest, MultiplePatchedServices) { #endif } +TEST(ServiceResolverTest, LocalPatchesAllowed) { + sandbox::ServiceResolverThunk* resolver = GetTestResolver(true); + + HMODULE ntdll_base = ::GetModuleHandle(L"ntdll.dll"); + ASSERT_TRUE(NULL != ntdll_base); + + const char kFunctionName[] = "NtClose"; + + void* target = ::GetProcAddress(ntdll_base, kFunctionName); + ASSERT_TRUE(NULL != target); + + BYTE service[50]; + memcpy(service, target, sizeof(service)); + static_cast<WinXpResolverTest*>(resolver)->set_target(service); + + // Any pointer will do as an interception_entry_point + void* function_entry = resolver; + size_t thunk_size = resolver->GetThunkSize(); + scoped_ptr<char[]> thunk(new char[thunk_size]); + size_t used; + + NTSTATUS ret = STATUS_UNSUCCESSFUL; + + // First try patching without having allowed local patches. + ret = resolver->Setup(ntdll_base, NULL, kFunctionName, NULL, + function_entry, thunk.get(), thunk_size, + &used); + EXPECT_FALSE(NT_SUCCESS(ret)); + + // Now allow local patches and check that things work. + resolver->AllowLocalPatches(); + ret = resolver->Setup(ntdll_base, NULL, kFunctionName, NULL, + function_entry, thunk.get(), thunk_size, + &used); + EXPECT_EQ(STATUS_SUCCESS, ret); +} + } // namespace diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc index f5c479a..cb366a6 100644 --- a/sandbox/win/src/win_utils.cc +++ b/sandbox/win/src/win_utils.cc @@ -6,10 +6,10 @@ #include <map> -#include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "sandbox/win/src/internal_types.h" #include "sandbox/win/src/nt_internals.h" +#include "sandbox/win/src/sandbox_nt_util.h" namespace { @@ -104,7 +104,7 @@ DWORD IsReparsePoint(const std::wstring& full_path, bool* result) { error != ERROR_PATH_NOT_FOUND && error != ERROR_INVALID_NAME) { // Unexpected error. - NOTREACHED(); + NOTREACHED_NT(); return error; } } else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) { @@ -124,7 +124,7 @@ DWORD IsReparsePoint(const std::wstring& full_path, bool* result) { // we'll get from |handle| will be \device\harddiskvolume1\some\foo\bar. bool SameObject(HANDLE handle, const wchar_t* full_path) { std::wstring path(full_path); - DCHECK(!path.empty()); + DCHECK_NT(!path.empty()); // Check if it's a pipe. if (IsPipe(path)) @@ -319,5 +319,5 @@ void ResolveNTFunctionPtr(const char* name, void* ptr) { *function_ptr = ::GetProcAddress(ntdll, name); } - CHECK(*function_ptr); + CHECK_NT(*function_ptr); } |