diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-11 15:27:56 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-11 15:27:56 +0000 |
commit | eded774a2a93708b901101423fbd3ce537ced049 (patch) | |
tree | 640f4e6fa2d84b16ebba746109fa0c6b64447942 /sandbox | |
parent | b8df56efb6abde9b8e445fffed5cc13342ef94d9 (diff) | |
download | chromium_src-eded774a2a93708b901101423fbd3ce537ced049.zip chromium_src-eded774a2a93708b901101423fbd3ce537ced049.tar.gz chromium_src-eded774a2a93708b901101423fbd3ce537ced049.tar.bz2 |
Sandbox policy and intercepts for the MITIGATION_WIN32K_DISABLE policy for renderer processes.
This policy when set will prevent the renderer process from making Win32K.sys calls via user32/gdi32 on
Windows 8 and beyond.
The following intercepts are needed for getting basic renderer functionality.
1. gdi32!GdiDllInitialize:
2. gdi32!GetStockObject.
3. user32!RegisterClassW.
The above functions are called during renderer process initialization. We intercept these APIS by
EAT patching the corresponding dlls and return fake success values from those.
The intercepts live in the process_mitigations_win32k_interception.cc/.h files. The rest of the changes
are plumbing with the sandbox policy framework.
While basic renderers work well now on Windows 8, pepper flash does not as it sends an IPC to the renderer
to creating the transport DIB. Justin is aware of this problem and thinks we can workaround this.
BUG=365160
Added gdi and user32 interceptors for the win32k lockdown project.
Review URL: https://codereview.chromium.org/318603003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276407 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/win/sandbox_win.gypi | 6 | ||||
-rw-r--r-- | sandbox/win/src/interceptors.h | 4 | ||||
-rw-r--r-- | sandbox/win/src/interceptors_64.cc | 24 | ||||
-rw-r--r-- | sandbox/win/src/interceptors_64.h | 14 | ||||
-rw-r--r-- | sandbox/win/src/ipc_tags.h | 3 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_test.cc | 51 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_dispatcher.cc | 57 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_dispatcher.h | 31 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_interception.cc | 29 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_interception.h | 46 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_policy.cc | 24 | ||||
-rw-r--r-- | sandbox/win/src/process_mitigations_win32k_policy.h | 35 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy.h | 8 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy_base.cc | 17 |
14 files changed, 343 insertions, 6 deletions
diff --git a/sandbox/win/sandbox_win.gypi b/sandbox/win/sandbox_win.gypi index 01d3f12..7d9cf94 100644 --- a/sandbox/win/sandbox_win.gypi +++ b/sandbox/win/sandbox_win.gypi @@ -74,6 +74,12 @@ 'src/policy_target.h', 'src/process_mitigations.cc', 'src/process_mitigations.h', + 'src/process_mitigations_win32k_dispatcher.cc', + 'src/process_mitigations_win32k_dispatcher.h', + 'src/process_mitigations_win32k_interception.cc', + 'src/process_mitigations_win32k_interception.h', + 'src/process_mitigations_win32k_policy.cc', + 'src/process_mitigations_win32k_policy.h', 'src/process_thread_dispatcher.cc', 'src/process_thread_dispatcher.h', 'src/process_thread_interception.cc', diff --git a/sandbox/win/src/interceptors.h b/sandbox/win/src/interceptors.h index ae3ecc6..a17447a 100644 --- a/sandbox/win/src/interceptors.h +++ b/sandbox/win/src/interceptors.h @@ -41,6 +41,10 @@ enum InterceptorId { // Sync dispatcher: CREATE_EVENT_ID, OPEN_EVENT_ID, + // Process mitigations Win32k dispatcher: + GDIINITIALIZE_ID, + GETSTOCKOBJECT_ID, + REGISTERCLASSW_ID, INTERCEPTOR_MAX_ID }; diff --git a/sandbox/win/src/interceptors_64.cc b/sandbox/win/src/interceptors_64.cc index f279b16..ef0b5f0 100644 --- a/sandbox/win/src/interceptors_64.cc +++ b/sandbox/win/src/interceptors_64.cc @@ -8,6 +8,7 @@ #include "sandbox/win/src/filesystem_interception.h" #include "sandbox/win/src/named_pipe_interception.h" #include "sandbox/win/src/policy_target.h" +#include "sandbox/win/src/process_mitigations_win32k_interception.h" #include "sandbox/win/src/process_thread_interception.h" #include "sandbox/win/src/registry_interception.h" #include "sandbox/win/src/sandbox_nt_types.h" @@ -251,4 +252,27 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenEvent64( object_attributes); } +// ----------------------------------------------------------------------- + +SANDBOX_INTERCEPT BOOL WINAPI TargetGdiDllInitialize64( + HANDLE dll, + DWORD reason) { + GdiDllInitializeFunction orig_fn = reinterpret_cast< + GdiDllInitializeFunction>(g_originals[GDIINITIALIZE_ID]); + return TargetGdiDllInitialize(orig_fn, dll, reason); +} + +SANDBOX_INTERCEPT HGDIOBJ WINAPI TargetGetStockObject64(int object) { + GetStockObjectFunction orig_fn = reinterpret_cast< + GetStockObjectFunction>(g_originals[GETSTOCKOBJECT_ID]); + return TargetGetStockObject(orig_fn, object); +} + +SANDBOX_INTERCEPT ATOM WINAPI TargetRegisterClassW64( + const WNDCLASS* wnd_class) { + RegisterClassWFunction orig_fn = reinterpret_cast< + RegisterClassWFunction>(g_originals[REGISTERCLASSW_ID]); + return TargetRegisterClassW(orig_fn, wnd_class); +} + } // namespace sandbox diff --git a/sandbox/win/src/interceptors_64.h b/sandbox/win/src/interceptors_64.h index 2ff31a8..7368ceb 100644 --- a/sandbox/win/src/interceptors_64.h +++ b/sandbox/win/src/interceptors_64.h @@ -154,6 +154,20 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenEvent64( PHANDLE event_handle, ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes); +// ----------------------------------------------------------------------- +// Interceptors handled by the process mitigations win32k lockdown code. + +// Interceptor for the GdiDllInitialize function. +SANDBOX_INTERCEPT BOOL WINAPI TargetGdiDllInitialize64( + HANDLE dll, + DWORD reason); + +// Interceptor for the GetStockObject function. +SANDBOX_INTERCEPT HGDIOBJ WINAPI TargetGetStockObject64(int object); + +// Interceptor for the RegisterClassW function. +SANDBOX_INTERCEPT ATOM WINAPI TargetRegisterClassW64(const WNDCLASS* wnd_class); + } // extern "C" } // namespace sandbox diff --git a/sandbox/win/src/ipc_tags.h b/sandbox/win/src/ipc_tags.h index 4e3a806..d680411 100644 --- a/sandbox/win/src/ipc_tags.h +++ b/sandbox/win/src/ipc_tags.h @@ -29,6 +29,9 @@ enum { IPC_NTCREATEKEY_TAG, IPC_NTOPENKEY_TAG, IPC_DUPLICATEHANDLEPROXY_TAG, + IPC_GDI_GDIDLLINITIALIZE_TAG, + IPC_GDI_GETSTOCKOBJECT_TAG, + IPC_USER_REGISTERCLASSW_TAG, IPC_LAST_TAG }; diff --git a/sandbox/win/src/process_mitigations_test.cc b/sandbox/win/src/process_mitigations_test.cc index 19e55ba..e606256 100644 --- a/sandbox/win/src/process_mitigations_test.cc +++ b/sandbox/win/src/process_mitigations_test.cc @@ -88,7 +88,6 @@ SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) { reinterpret_cast<GetProcessMitigationPolicyFunction>( ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy")); - if (!get_process_mitigation_policy) return SBOX_TEST_NOT_FOUND; @@ -103,9 +102,6 @@ SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) { if (!CheckWin8StrictHandlePolicy()) return SBOX_TEST_THIRD_ERROR; - if (!CheckWin8Win32CallPolicy()) - return SBOX_TEST_FOURTH_ERROR; - if (!CheckWin8DllExtensionPolicy()) return SBOX_TEST_FIFTH_ERROR; @@ -201,5 +197,52 @@ TEST(ProcessMitigationsTest, CheckDep) { } #endif +SBOX_TESTS_COMMAND int CheckWin8Lockdown(int argc, wchar_t **argv) { + get_process_mitigation_policy = + reinterpret_cast<GetProcessMitigationPolicyFunction>( + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), + "GetProcessMitigationPolicy")); + if (!get_process_mitigation_policy) + return SBOX_TEST_NOT_FOUND; + + if (!CheckWin8Win32CallPolicy()) + return SBOX_TEST_FIRST_ERROR; + return SBOX_TEST_SUCCEEDED; +} + +// This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation on +// the target process causes the launch to fail in process initialization. +// The test process itself links against user32/gdi32. +TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownFailure) { + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return; + + TestRunner runner; + sandbox::TargetPolicy* policy = runner.GetPolicy(); + + EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE), + SBOX_ALL_OK); + EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown")); +} + +// This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation +// along with the policy to fake user32 and gdi32 initialization successfully +// launches the target process. +// The test process itself links against user32/gdi32. +TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) { + if (base::win::GetVersion() < base::win::VERSION_WIN8) + return; + + TestRunner runner; + sandbox::TargetPolicy* policy = runner.GetPolicy(); + + EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE), + SBOX_ALL_OK); + EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN, + sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL), + sandbox::SBOX_ALL_OK); + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown")); +} + } // namespace sandbox diff --git a/sandbox/win/src/process_mitigations_win32k_dispatcher.cc b/sandbox/win/src/process_mitigations_win32k_dispatcher.cc new file mode 100644 index 0000000..e426084 --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_dispatcher.cc @@ -0,0 +1,57 @@ +// Copyright 2014 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/process_mitigations_win32k_dispatcher.h" +#include "sandbox/win/src/interception.h" +#include "sandbox/win/src/interceptors.h" +#include "sandbox/win/src/ipc_tags.h" +#include "sandbox/win/src/process_mitigations_win32k_interception.h" + +namespace sandbox { + +ProcessMitigationsWin32KDispatcher::ProcessMitigationsWin32KDispatcher( + PolicyBase* policy_base) + : policy_base_(policy_base) { +} + +bool ProcessMitigationsWin32KDispatcher::SetupService( + InterceptionManager* manager, int service) { + if (!(policy_base_->GetProcessMitigations() & + sandbox::MITIGATION_WIN32K_DISABLE)) { + return false; + } + + switch (service) { + case IPC_GDI_GDIDLLINITIALIZE_TAG: { + if (!INTERCEPT_EAT(manager, L"gdi32.dll", GdiDllInitialize, + GDIINITIALIZE_ID, 12)) { + return false; + } + return true; + } + + case IPC_GDI_GETSTOCKOBJECT_TAG: { + if (!INTERCEPT_EAT(manager, L"gdi32.dll", GetStockObject, + GETSTOCKOBJECT_ID, 8)) { + return false; + } + return true; + } + + case IPC_USER_REGISTERCLASSW_TAG: { + if (!INTERCEPT_EAT(manager, L"user32.dll", RegisterClassW, + REGISTERCLASSW_ID, 8)) { + return false; + } + return true; + } + + default: + break; + } + return false; +} + +} // namespace sandbox + diff --git a/sandbox/win/src/process_mitigations_win32k_dispatcher.h b/sandbox/win/src/process_mitigations_win32k_dispatcher.h new file mode 100644 index 0000000..65c9f77 --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_dispatcher.h @@ -0,0 +1,31 @@ +// Copyright 2014 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. + +#ifndef SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_DISPATCHER_H_ +#define SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_DISPATCHER_H_ + +#include "base/basictypes.h" +#include "sandbox/win/src/sandbox_policy_base.h" + +namespace sandbox { + +// This class sets up intercepts for the Win32K lockdown policy which is set +// on Windows 8 and beyond. +class ProcessMitigationsWin32KDispatcher : public Dispatcher { + public: + explicit ProcessMitigationsWin32KDispatcher(PolicyBase* policy_base); + ~ProcessMitigationsWin32KDispatcher() {} + + // Dispatcher interface. + virtual bool SetupService(InterceptionManager* manager, int service); + + private: + PolicyBase* policy_base_; + + DISALLOW_COPY_AND_ASSIGN(ProcessMitigationsWin32KDispatcher); +}; + +} // namespace sandbox + +#endif // SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_DISPATCHER_H_ diff --git a/sandbox/win/src/process_mitigations_win32k_interception.cc b/sandbox/win/src/process_mitigations_win32k_interception.cc new file mode 100644 index 0000000..ee24fbf --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_interception.cc @@ -0,0 +1,29 @@ +// Copyright 2014 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/process_mitigations_win32k_interception.h" + +namespace sandbox { + +BOOL WINAPI TargetGdiDllInitialize( + GdiDllInitializeFunction orig_gdi_dll_initialize, + HANDLE dll, + DWORD reason) { + return TRUE; +} + +HGDIOBJ WINAPI TargetGetStockObject( + GetStockObjectFunction orig_get_stock_object, + int object) { + return reinterpret_cast<HGDIOBJ>(NULL); +} + +ATOM WINAPI TargetRegisterClassW( + RegisterClassWFunction orig_register_class_function, + const WNDCLASS* wnd_class) { + return TRUE; +} + +} // namespace sandbox + diff --git a/sandbox/win/src/process_mitigations_win32k_interception.h b/sandbox/win/src/process_mitigations_win32k_interception.h new file mode 100644 index 0000000..bf7b551 --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_interception.h @@ -0,0 +1,46 @@ +// Copyright 2014 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. + +#ifndef SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_INTERCEPTION_H_ +#define SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_INTERCEPTION_H_ + +#include <windows.h> +#include "base/basictypes.h" +#include "sandbox/win/src/sandbox_types.h" + +namespace sandbox { + +extern "C" { + +typedef BOOL (WINAPI* GdiDllInitializeFunction) ( + HANDLE dll, + DWORD reason, + LPVOID reserved); + +typedef HGDIOBJ (WINAPI *GetStockObjectFunction) (int object); + +typedef ATOM (WINAPI *RegisterClassWFunction) (const WNDCLASS* wnd_class); + +// Interceptor for the GdiDllInitialize function. +SANDBOX_INTERCEPT BOOL WINAPI TargetGdiDllInitialize( + GdiDllInitializeFunction orig_gdi_dll_initialize, + HANDLE dll, + DWORD reason); + +// Interceptor for the GetStockObject function. +SANDBOX_INTERCEPT HGDIOBJ WINAPI TargetGetStockObject( + GetStockObjectFunction orig_get_stock_object, + int object); + +// Interceptor for the RegisterClassW function. +SANDBOX_INTERCEPT ATOM WINAPI TargetRegisterClassW( + RegisterClassWFunction orig_register_class_function, + const WNDCLASS* wnd_class); + +} // extern "C" + +} // namespace sandbox + +#endif // SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_INTERCEPTION_H_ + diff --git a/sandbox/win/src/process_mitigations_win32k_policy.cc b/sandbox/win/src/process_mitigations_win32k_policy.cc new file mode 100644 index 0000000..af18c54 --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_policy.cc @@ -0,0 +1,24 @@ +// Copyright 2014 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/process_mitigations_win32k_policy.h" + +namespace sandbox { + +bool ProcessMitigationsWin32KLockdownPolicy::GenerateRules( + const wchar_t* name, + TargetPolicy::Semantics semantics, + LowLevelPolicy* policy) { + PolicyRule rule(FAKE_SUCCESS); + if (!policy->AddRule(IPC_GDI_GDIDLLINITIALIZE_TAG, &rule)) + return false; + if (!policy->AddRule(IPC_GDI_GETSTOCKOBJECT_TAG, &rule)) + return false; + if (!policy->AddRule(IPC_USER_REGISTERCLASSW_TAG, &rule)) + return false; + return true; +} + +} // namespace sandbox + diff --git a/sandbox/win/src/process_mitigations_win32k_policy.h b/sandbox/win/src/process_mitigations_win32k_policy.h new file mode 100644 index 0000000..078ed2b --- /dev/null +++ b/sandbox/win/src/process_mitigations_win32k_policy.h @@ -0,0 +1,35 @@ +// Copyright 2014 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. + +#ifndef SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_POLICY_H_ +#define SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_POLICY_H_ + +#include "base/basictypes.h" +#include "sandbox/win/src/crosscall_server.h" +#include "sandbox/win/src/policy_low_level.h" +#include "sandbox/win/src/sandbox_policy.h" + +namespace sandbox { + +enum EvalResult; + +// This class centralizes most of the knowledge related to the process +// mitigations Win32K lockdown policy. +class ProcessMitigationsWin32KLockdownPolicy { + public: + // Creates the required low-level policy rules to evaluate a high-level + // policy rule for the Win32K process mitigation policy. + // name is the object name, semantics is the desired semantics for the + // open or create and policy is the policy generator to which the rules are + // going to be added. + static bool GenerateRules(const wchar_t* name, + TargetPolicy::Semantics semantics, + LowLevelPolicy* policy); +}; + +} // namespace sandbox + +#endif // SANDBOX_SRC_PROCESS_MITIGATIONS_WIN32K_POLICY_H_ + + diff --git a/sandbox/win/src/sandbox_policy.h b/sandbox/win/src/sandbox_policy.h index 9379d45..22a2049 100644 --- a/sandbox/win/src/sandbox_policy.h +++ b/sandbox/win/src/sandbox_policy.h @@ -26,7 +26,8 @@ class TargetPolicy { SUBSYS_PROCESS, // Creation of child processes. SUBSYS_REGISTRY, // Creation and opening of registry keys. SUBSYS_SYNC, // Creation of named sync objects. - SUBSYS_HANDLES // Duplication of handles to other processes. + SUBSYS_HANDLES, // Duplication of handles to other processes. + SUBSYS_WIN32K_LOCKDOWN // Win32K Lockdown related policy. }; // Allowable semantics when a rule is matched. @@ -52,7 +53,10 @@ class TargetPolicy { EVENTS_ALLOW_ANY, // Allows the creation of an event with full access. EVENTS_ALLOW_READONLY, // Allows opening an even with synchronize access. REG_ALLOW_READONLY, // Allows readonly access to a registry key. - REG_ALLOW_ANY // Allows read and write access to a registry key. + REG_ALLOW_ANY, // Allows read and write access to a registry key. + FAKE_USER_GDI_INIT // Fakes user32 and gdi32 initialization. This can + // be used to allow the DLLs to load and initialize + // even if the process cannot access that subsystem. }; // Increments the reference count of this object. The reference count must diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index ca946a4..711fafc 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc @@ -21,6 +21,8 @@ #include "sandbox/win/src/policy_broker.h" #include "sandbox/win/src/policy_engine_processor.h" #include "sandbox/win/src/policy_low_level.h" +#include "sandbox/win/src/process_mitigations_win32k_dispatcher.h" +#include "sandbox/win/src/process_mitigations_win32k_policy.h" #include "sandbox/win/src/process_thread_dispatcher.h" #include "sandbox/win/src/process_thread_policy.h" #include "sandbox/win/src/registry_dispatcher.h" @@ -125,6 +127,11 @@ PolicyBase::PolicyBase() dispatcher = new HandleDispatcher(this); ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher; + + dispatcher = new ProcessMitigationsWin32KDispatcher(this); + ipc_targets_[IPC_GDI_GDIDLLINITIALIZE_TAG] = dispatcher; + ipc_targets_[IPC_GDI_GETSTOCKOBJECT_TAG] = dispatcher; + ipc_targets_[IPC_USER_REGISTERCLASSW_TAG] = dispatcher; } PolicyBase::~PolicyBase() { @@ -425,6 +432,16 @@ ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics, } break; } + + case SUBSYS_WIN32K_LOCKDOWN: { + if (!ProcessMitigationsWin32KLockdownPolicy::GenerateRules( + pattern, semantics,policy_maker_)) { + NOTREACHED(); + return SBOX_ERROR_BAD_PARAMS; + } + break; + } + default: { return SBOX_ERROR_UNSUPPORTED; } |