summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
authorrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 03:12:21 +0000
committerrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-04 03:12:21 +0000
commit1fa91d332a52fc3d11eff61b95a270686af8e587 (patch)
treeb790dc02750d9144530e46ee1f6e8d28c409c315 /sandbox
parent6e6a9edf41e9cf09c6d3bb580d1398f3161c8f47 (diff)
downloadchromium_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.gypi1
-rw-r--r--sandbox/win/src/nt_internals.h7
-rw-r--r--sandbox/win/src/policy_broker.cc1
-rw-r--r--sandbox/win/src/sandbox.cc2
-rw-r--r--sandbox/win/src/sandbox_globals.cc18
-rw-r--r--sandbox/win/src/sandbox_nt_types.h1
-rw-r--r--sandbox/win/src/sandbox_nt_util.cc12
-rw-r--r--sandbox/win/src/sandbox_nt_util.h3
-rw-r--r--sandbox/win/src/sandbox_utils.cc4
-rw-r--r--sandbox/win/src/sandbox_utils.h8
-rw-r--r--sandbox/win/src/service_resolver.cc12
-rw-r--r--sandbox/win/src/service_resolver.h3
-rw-r--r--sandbox/win/src/service_resolver_64.cc16
-rw-r--r--sandbox/win/src/service_resolver_unittest.cc41
-rw-r--r--sandbox/win/src/win_utils.cc8
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);
}