summaryrefslogtreecommitdiffstats
path: root/sandbox/src
diff options
context:
space:
mode:
authorjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-24 17:20:34 +0000
committerjschuh@chromium.org <jschuh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-24 17:20:34 +0000
commit4a675af846624bccd583b8ae6b518391018ee6a6 (patch)
treef931ebaf34d7e451a10f9870f476919b8b611d55 /sandbox/src
parent65533ad0606a04de3746da2bc785702ba3da17b5 (diff)
downloadchromium_src-4a675af846624bccd583b8ae6b518391018ee6a6.zip
chromium_src-4a675af846624bccd583b8ae6b518391018ee6a6.tar.gz
chromium_src-4a675af846624bccd583b8ae6b518391018ee6a6.tar.bz2
Close all open ALPC client ports at lockdown.
Close out the CSRSS and LSASS ALPC client ports that are opened during initialization. BUG=58069 TEST=sbox_integration_tests --gtest_filter=HandleCloserTests.RunThreadPool Review URL: http://codereview.chromium.org/7490002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/src')
-rw-r--r--sandbox/src/handle_closer.cc17
-rw-r--r--sandbox/src/handle_closer.h4
-rw-r--r--sandbox/src/handle_closer_test.cc49
-rw-r--r--sandbox/src/interceptors.h4
-rw-r--r--sandbox/src/interceptors_64.cc12
-rw-r--r--sandbox/src/interceptors_64.h8
-rw-r--r--sandbox/src/nt_internals.h14
-rw-r--r--sandbox/src/policy_broker.cc1
-rw-r--r--sandbox/src/process_thread_interception.cc30
-rw-r--r--sandbox/src/process_thread_interception.h17
-rw-r--r--sandbox/src/sandbox_nt_types.h1
-rw-r--r--sandbox/src/sandbox_policy_base.cc3
12 files changed, 154 insertions, 6 deletions
diff --git a/sandbox/src/handle_closer.cc b/sandbox/src/handle_closer.cc
index 4a08d2f..3ac802e 100644
--- a/sandbox/src/handle_closer.cc
+++ b/sandbox/src/handle_closer.cc
@@ -6,7 +6,11 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/win/windows_version.h"
+#include "sandbox/src/interceptors.h"
+#include "sandbox/src/internal_types.h"
#include "sandbox/src/nt_internals.h"
+#include "sandbox/src/process_thread_interception.h"
#include "sandbox/src/win_utils.h"
namespace {
@@ -149,6 +153,19 @@ bool HandleCloser::SetupHandleList(void* buffer, size_t buffer_bytes) {
return output <= end;
}
+bool HandleCloser::SetupHandleInterceptions(InterceptionManager* manager) {
+ // We need to intercept CreateThread if we're closing ALPC port clients.
+ HandleMap::iterator names = handles_to_close_.find(L"ALPC Port");
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA &&
+ names != handles_to_close_.end() &&
+ (names->second.empty() || names->second.size() == 0)) {
+ return INTERCEPT_EAT(manager, kKerneldllName, CreateThread,
+ CREATE_THREAD_ID, 28);
+ }
+
+ return true;
+}
+
bool GetHandleName(HANDLE handle, string16* handle_name) {
static NtQueryObject QueryObject = NULL;
if (!QueryObject)
diff --git a/sandbox/src/handle_closer.h b/sandbox/src/handle_closer.h
index 7252968..76b1a51 100644
--- a/sandbox/src/handle_closer.h
+++ b/sandbox/src/handle_closer.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
+#include "sandbox/src/interception.h"
#include "sandbox/src/sandbox_types.h"
#include "sandbox/src/target_process.h"
@@ -51,6 +52,9 @@ class HandleCloser {
// Serializes and copies the closer table into the target process.
bool InitializeTargetHandles(TargetProcess* target);
+ // Adds any interceptions that may be required due to closed system handles.
+ bool SetupHandleInterceptions(InterceptionManager* manager);
+
private:
// Calculates the memory needed to copy the serialized handles list (rounded
// to the nearest machine-word size).
diff --git a/sandbox/src/handle_closer_test.cc b/sandbox/src/handle_closer_test.cc
index b4d02d8..81b6db2 100644
--- a/sandbox/src/handle_closer_test.cc
+++ b/sandbox/src/handle_closer_test.cc
@@ -42,6 +42,10 @@ HANDLE GetMarkerFile(const wchar_t *extension) {
NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
}
+// Used by the thread pool tests.
+HANDLE finish_event;
+const int kWaitCount = 20;
+
} // namespace
namespace sandbox {
@@ -142,4 +146,49 @@ TEST(HandleCloserTest, CloseMarkerFiles) {
"Failed: " << command;
}
+void WINAPI ThreadPoolTask(void* event, BOOLEAN timeout) {
+ static volatile LONG waiters_remaining = kWaitCount;
+ CHECK(!timeout);
+ CHECK(::CloseHandle(event));
+ if (::InterlockedDecrement(&waiters_remaining) == 0)
+ CHECK(::SetEvent(finish_event));
+}
+
+// Run a thread pool inside a sandbox without a CSRSS connection.
+SBOX_TESTS_COMMAND int RunThreadPool(int argc, wchar_t **argv) {
+ HANDLE wait_list[20];
+ CHECK(finish_event = ::CreateEvent(NULL, TRUE, FALSE, NULL));
+
+ // Set up a bunch of waiters.
+ HANDLE pool = NULL;
+ for (int i = 0; i < kWaitCount; ++i) {
+ HANDLE event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ CHECK(event);
+ CHECK(::RegisterWaitForSingleObject(&pool, event, ThreadPoolTask, event,
+ INFINITE, WT_EXECUTEONLYONCE));
+ wait_list[i] = event;
+ }
+
+ // Signal all the waiters.
+ for (int i = 0; i < kWaitCount; ++i)
+ CHECK(::SetEvent(wait_list[i]));
+
+ CHECK_EQ(::WaitForSingleObject(finish_event, INFINITE), WAIT_OBJECT_0);
+ CHECK(::CloseHandle(finish_event));
+
+ return SBOX_TEST_SUCCEEDED;
+}
+
+TEST(HandleCloserTest, RunThreadPool) {
+ TestRunner runner;
+ runner.SetTimeout(2000);
+ runner.SetTestState(AFTER_REVERT);
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ // Sever the CSRSS connection by closing ALPC ports inside the sandbox.
+ CHECK_EQ(policy->AddKernelObjectToClose(L"ALPC Port", NULL), SBOX_ALL_OK);
+
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"RunThreadPool"));
+}
+
} // namespace sandbox
diff --git a/sandbox/src/interceptors.h b/sandbox/src/interceptors.h
index 2b033b6..3f690ae 100644
--- a/sandbox/src/interceptors.h
+++ b/sandbox/src/interceptors.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -41,6 +41,8 @@ enum InterceptorId {
// Sync dispatcher:
CREATE_EVENT_ID,
OPEN_EVENT_ID,
+ // CSRSS bypass for HandleCloser:
+ CREATE_THREAD_ID,
INTERCEPTOR_MAX_ID
};
diff --git a/sandbox/src/interceptors_64.cc b/sandbox/src/interceptors_64.cc
index 29d59143..d1b9718 100644
--- a/sandbox/src/interceptors_64.cc
+++ b/sandbox/src/interceptors_64.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -68,6 +68,16 @@ NTSTATUS WINAPI TargetNtOpenThreadTokenEx64(
open_as_self, handle_attributes, token);
}
+HANDLE WINAPI TargetCreateThread64(LPSECURITY_ATTRIBUTES thread_attributes,
+ SIZE_T stack_size, LPTHREAD_START_ROUTINE start_address,
+ PVOID parameter, DWORD creation_flags, LPDWORD thread_id) {
+ CreateThreadFunction orig_fn = reinterpret_cast<
+ CreateThreadFunction>(g_originals[CREATE_THREAD_ID]);
+ return TargetCreateThread(orig_fn, thread_attributes, stack_size,
+ start_address, parameter, creation_flags,
+ thread_id);
+}
+
// -----------------------------------------------------------------------
SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtCreateFile64(
diff --git a/sandbox/src/interceptors_64.h b/sandbox/src/interceptors_64.h
index 10dff4f..5fc0a4b 100644
--- a/sandbox/src/interceptors_64.h
+++ b/sandbox/src/interceptors_64.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -44,6 +44,12 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadTokenEx64(
HANDLE thread, ACCESS_MASK desired_access, BOOLEAN open_as_self,
ULONG handle_attributes, PHANDLE token);
+// Interception of CreateThread on the child process.
+SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateThread64(
+ LPSECURITY_ATTRIBUTES thread_attributes, SIZE_T stack_size,
+ LPTHREAD_START_ROUTINE start_address, PVOID parameter,
+ DWORD creation_flags, LPDWORD thread_id);
+
// -----------------------------------------------------------------------
// Interceptors handled by the file system dispatcher.
diff --git a/sandbox/src/nt_internals.h b/sandbox/src/nt_internals.h
index 08bf1a1..e0bc6e3 100644
--- a/sandbox/src/nt_internals.h
+++ b/sandbox/src/nt_internals.h
@@ -338,6 +338,18 @@ typedef NTSTATUS (WINAPI *NtOpenProcessTokenExFunction) (
IN ULONG HandleAttributes,
OUT PHANDLE TokenHandle);
+typedef NTSTATUS (WINAPI * RtlCreateUserThreadFunction)(
+ IN HANDLE Process,
+ IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
+ IN BOOLEAN CreateSuspended,
+ IN ULONG ZeroBits,
+ IN SIZE_T MaximumStackSize,
+ IN SIZE_T CommittedStackSize,
+ IN LPTHREAD_START_ROUTINE StartAddress,
+ IN PVOID Parameter,
+ OUT PHANDLE Thread,
+ OUT PCLIENT_ID ClientId);
+
// -----------------------------------------------------------------------
// Registry
@@ -454,7 +466,7 @@ typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION {
ULONG HandleCount;
ULONG PointerCount;
ULONG Reserved[10]; // reserved for internal use
- } PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
+} PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION;
typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
UNICODE_STRING TypeName;
diff --git a/sandbox/src/policy_broker.cc b/sandbox/src/policy_broker.cc
index 0a63750..9882f38 100644
--- a/sandbox/src/policy_broker.cc
+++ b/sandbox/src/policy_broker.cc
@@ -68,6 +68,7 @@ bool SetupNtdllImports(TargetProcess *child) {
INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString);
INIT_GLOBAL_RTL(RtlCompareUnicodeString);
INIT_GLOBAL_RTL(RtlCreateHeap);
+ INIT_GLOBAL_RTL(RtlCreateUserThread);
INIT_GLOBAL_RTL(RtlDestroyHeap);
INIT_GLOBAL_RTL(RtlFreeHeap);
INIT_GLOBAL_RTL(_strnicmp);
diff --git a/sandbox/src/process_thread_interception.cc b/sandbox/src/process_thread_interception.cc
index fdb5644..5a3119f 100644
--- a/sandbox/src/process_thread_interception.cc
+++ b/sandbox/src/process_thread_interception.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2011 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.
@@ -15,6 +15,8 @@
namespace sandbox {
+SANDBOX_INTERCEPT NtExports g_nt;
+
// Hooks NtOpenThread and proxy the call to the broker if it's trying to
// open a thread in the same process.
NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
@@ -396,4 +398,30 @@ BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
return FALSE;
}
+// Creates a thread without registering with CSRSS. This is required if we
+// closed the CSRSS ALPC port after lockdown.
+HANDLE WINAPI TargetCreateThread(CreateThreadFunction orig_CreateThread,
+ LPSECURITY_ATTRIBUTES thread_attributes,
+ SIZE_T stack_size,
+ LPTHREAD_START_ROUTINE start_address,
+ PVOID parameter,
+ DWORD creation_flags,
+ LPDWORD thread_id) {
+ HANDLE thread;
+ PSECURITY_DESCRIPTOR sd =
+ thread_attributes ? thread_attributes->lpSecurityDescriptor : NULL;
+ CLIENT_ID client_id;
+
+ NTSTATUS result = g_nt.RtlCreateUserThread(NtCurrentProcess, sd,
+ creation_flags & CREATE_SUSPENDED,
+ 0, stack_size, 0, start_address,
+ parameter, &thread, &client_id);
+ if (!NT_SUCCESS(result))
+ return 0;
+
+ if (thread_id)
+ *thread_id = HandleToUlong(client_id.UniqueThread);
+ return thread;
+}
+
} // namespace sandbox
diff --git a/sandbox/src/process_thread_interception.h b/sandbox/src/process_thread_interception.h
index 6fa3349..e73689d 100644
--- a/sandbox/src/process_thread_interception.h
+++ b/sandbox/src/process_thread_interception.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2011 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.
@@ -36,6 +36,14 @@ typedef BOOL (WINAPI *CreateProcessAFunction)(
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation);
+typedef HANDLE (WINAPI *CreateThreadFunction)(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ PVOID lpParameter,
+ DWORD dwCreationFlags,
+ LPDWORD lpThreadId);
+
// Interception of NtOpenThread on the child process.
SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThread(
NtOpenThreadFunction orig_OpenThread, PHANDLE thread,
@@ -73,6 +81,13 @@ SANDBOX_INTERCEPT BOOL WINAPI TargetCreateProcessA(
LPVOID environment, LPCSTR current_directory, LPSTARTUPINFOA startup_info,
LPPROCESS_INFORMATION process_information);
+// Interception of CreateThread in kernel32.dll.
+SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateThread(
+ CreateThreadFunction orig_CreateThread,
+ LPSECURITY_ATTRIBUTES thread_attributes, SIZE_T stack_size,
+ LPTHREAD_START_ROUTINE start_address, PVOID parameter,
+ DWORD creation_flags, LPDWORD thread_id);
+
} // extern "C"
} // namespace sandbox
diff --git a/sandbox/src/sandbox_nt_types.h b/sandbox/src/sandbox_nt_types.h
index 144dbd1..d0d24f8 100644
--- a/sandbox/src/sandbox_nt_types.h
+++ b/sandbox/src/sandbox_nt_types.h
@@ -25,6 +25,7 @@ struct NtExports {
RtlAnsiStringToUnicodeStringFunction RtlAnsiStringToUnicodeString;
RtlCompareUnicodeStringFunction RtlCompareUnicodeString;
RtlCreateHeapFunction RtlCreateHeap;
+ RtlCreateUserThreadFunction RtlCreateUserThread;
RtlDestroyHeapFunction RtlDestroyHeap;
RtlFreeHeapFunction RtlFreeHeap;
_strnicmpFunction _strnicmp;
diff --git a/sandbox/src/sandbox_policy_base.cc b/sandbox/src/sandbox_policy_base.cc
index 8e25b71..e65f648 100644
--- a/sandbox/src/sandbox_policy_base.cc
+++ b/sandbox/src/sandbox_policy_base.cc
@@ -441,6 +441,9 @@ bool PolicyBase::SetupAllInterceptions(TargetProcess* target) {
}
}
+ if (!handle_closer_.SetupHandleInterceptions(&manager))
+ return false;
+
if (!SetupBasicInterceptions(&manager))
return false;