diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-27 23:38:45 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-27 23:38:45 +0000 |
commit | 3f7007a10ebe3765ec056d067a5c9f69c0a0e9bc (patch) | |
tree | fc6d28e784e58d807af8bcd30b99fa9b9c10357f /sandbox | |
parent | 79b3d1637f84df9bd1fb91387db00adf38476d67 (diff) | |
download | chromium_src-3f7007a10ebe3765ec056d067a5c9f69c0a0e9bc.zip chromium_src-3f7007a10ebe3765ec056d067a5c9f69c0a0e9bc.tar.gz chromium_src-3f7007a10ebe3765ec056d067a5c9f69c0a0e9bc.tar.bz2 |
Ensure that the gpu process can run in the restricted sandbox for the XP presentation path.
To achieve this we have to allow access to named events created by the dwmapi.dll. This is achieved by
intercepting the CreateEventW/A/OpenEventW/A APIs and proxying them to the broker.
On Windows 8 we need to intercept the kernelbase.dll and kernel32 on previous operating system versions.
BUG=299047
R=cpu@chromium.org, rvargas@chromium.org, cpu, rvargas
Review URL: https://codereview.chromium.org/23654049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225811 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/win/src/interceptors.h | 6 | ||||
-rw-r--r-- | sandbox/win/src/interceptors_64.cc | 20 | ||||
-rw-r--r-- | sandbox/win/src/interceptors_64.h | 9 | ||||
-rw-r--r-- | sandbox/win/src/sync_dispatcher.cc | 33 | ||||
-rw-r--r-- | sandbox/win/src/sync_interception.cc | 162 | ||||
-rw-r--r-- | sandbox/win/src/sync_interception.h | 40 |
6 files changed, 209 insertions, 61 deletions
diff --git a/sandbox/win/src/interceptors.h b/sandbox/win/src/interceptors.h index 43126d0..2e6dc8d 100644 --- a/sandbox/win/src/interceptors.h +++ b/sandbox/win/src/interceptors.h @@ -39,8 +39,10 @@ enum InterceptorId { OPEN_KEY_ID, OPEN_KEY_EX_ID, // Sync dispatcher: - CREATE_EVENT_ID, - OPEN_EVENT_ID, + CREATE_EVENTW_ID, + CREATE_EVENTA_ID, + OPEN_EVENTW_ID, + OPEN_EVENTA_ID, // CSRSS bypasses for HandleCloser: CREATE_THREAD_ID, GET_USER_DEFAULT_LCID_ID, diff --git a/sandbox/win/src/interceptors_64.cc b/sandbox/win/src/interceptors_64.cc index 30843fd..45d6b31 100644 --- a/sandbox/win/src/interceptors_64.cc +++ b/sandbox/win/src/interceptors_64.cc @@ -253,16 +253,32 @@ SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW64( LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset, BOOL initial_state, LPCWSTR name) { CreateEventWFunction orig_fn = reinterpret_cast< - CreateEventWFunction>(g_originals[CREATE_EVENT_ID]); + CreateEventWFunction>(g_originals[CREATE_EVENTW_ID]); return TargetCreateEventW(orig_fn, security_attributes, manual_reset, initial_state, name); } +SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventA64( + LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset, + BOOL initial_state, LPCSTR name) { + CreateEventAFunction orig_fn = reinterpret_cast< + CreateEventAFunction>(g_originals[CREATE_EVENTA_ID]); + return TargetCreateEventA(orig_fn, security_attributes, manual_reset, + initial_state, name); +} + SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW64( ACCESS_MASK desired_access, BOOL inherit_handle, LPCWSTR name) { OpenEventWFunction orig_fn = reinterpret_cast< - OpenEventWFunction>(g_originals[OPEN_EVENT_ID]); + OpenEventWFunction>(g_originals[OPEN_EVENTW_ID]); return TargetOpenEventW(orig_fn, desired_access, inherit_handle, name); } +SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventA64( + ACCESS_MASK desired_access, BOOL inherit_handle, LPCSTR name) { + OpenEventAFunction orig_fn = reinterpret_cast< + OpenEventAFunction>(g_originals[OPEN_EVENTA_ID]); + return TargetOpenEventA(orig_fn, desired_access, inherit_handle, name); +} + } // namespace sandbox diff --git a/sandbox/win/src/interceptors_64.h b/sandbox/win/src/interceptors_64.h index 87c1c50..3e4dad5 100644 --- a/sandbox/win/src/interceptors_64.h +++ b/sandbox/win/src/interceptors_64.h @@ -158,10 +158,19 @@ SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW64( LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset, BOOL initial_state, LPCWSTR name); +// Interception of CreateEventA on the child process. +SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventA64( + LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset, + BOOL initial_state, LPCSTR name); + // Interception of OpenEventW on the child process. SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW64( ACCESS_MASK desired_access, BOOL inherit_handle, LPCWSTR name); +// Interception of OpenEventA on the child process. +SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventA64( + ACCESS_MASK desired_access, BOOL inherit_handle, LPCSTR name); + } // extern "C" } // namespace sandbox diff --git a/sandbox/win/src/sync_dispatcher.cc b/sandbox/win/src/sync_dispatcher.cc index eb1c1e4..64b10c3 100644 --- a/sandbox/win/src/sync_dispatcher.cc +++ b/sandbox/win/src/sync_dispatcher.cc @@ -1,9 +1,10 @@ -// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. +// Copyright (c) 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/sync_dispatcher.h" +#include "base/win/windows_version.h" #include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/interception.h" #include "sandbox/win/src/interceptors.h" @@ -34,15 +35,29 @@ SyncDispatcher::SyncDispatcher(PolicyBase* policy_base) bool SyncDispatcher::SetupService(InterceptionManager* manager, int service) { - if (IPC_CREATEEVENT_TAG == service) - return INTERCEPT_EAT(manager, L"kernel32.dll", CreateEventW, - CREATE_EVENT_ID, 20); + bool ret = false; + static const wchar_t* kWin32SyncDllName = + base::win::GetVersion() >= base::win::VERSION_WIN8 ? kKernelBasedllName : + kKerneldllName; - if (IPC_OPENEVENT_TAG == service) - return INTERCEPT_EAT(manager, L"kernel32.dll", OpenEventW, - OPEN_EVENT_ID, 16); - - return false; + // We need to intercept kernelbase.dll on Windows 8 and beyond and + // kernel32.dll for earlier versions. + if (IPC_CREATEEVENT_TAG == service) { + ret = INTERCEPT_EAT(manager, kWin32SyncDllName, CreateEventW, + CREATE_EVENTW_ID, 20); + if (ret) { + ret = INTERCEPT_EAT(manager, kWin32SyncDllName, CreateEventA, + CREATE_EVENTA_ID, 20); + } + } else if (IPC_OPENEVENT_TAG == service) { + ret = INTERCEPT_EAT(manager, kWin32SyncDllName, OpenEventW, OPEN_EVENTW_ID, + 16); + if (ret) { + ret = INTERCEPT_EAT(manager, kWin32SyncDllName, OpenEventW, + OPEN_EVENTA_ID, 16); + } + } + return ret; } bool SyncDispatcher::CreateEvent(IPCInfo* ipc, std::wstring* name, diff --git a/sandbox/win/src/sync_interception.cc b/sandbox/win/src/sync_interception.cc index d235723..54dbcc14 100644 --- a/sandbox/win/src/sync_interception.cc +++ b/sandbox/win/src/sync_interception.cc @@ -15,47 +15,108 @@ namespace sandbox { +ResultCode ProxyCreateEvent(LPCWSTR name, + BOOL initial_state, + BOOL manual_reset, + CrossCallReturn* answer) { + void* memory = GetGlobalIPCMemory(); + if (!memory) + return SBOX_ERROR_GENERIC; + + CountedParameterSet<NameBased> params; + params[NameBased::NAME] = ParamPickerMake(name); + + if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase())) + return SBOX_ERROR_GENERIC; + + SharedMemIPCClient ipc(memory); + ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, manual_reset, + initial_state, answer); + return code; +} + +ResultCode ProxyOpenEvent(LPCWSTR name, + ACCESS_MASK desired_access, + BOOL inherit_handle, + CrossCallReturn* answer) { + void* memory = GetGlobalIPCMemory(); + if (!memory) + return SBOX_ERROR_GENERIC; + + uint32 inherit_handle_ipc = inherit_handle; + CountedParameterSet<OpenEventParams> params; + params[OpenEventParams::NAME] = ParamPickerMake(name); + params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access); + + if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase())) + return SBOX_ERROR_GENERIC; + + SharedMemIPCClient ipc(memory); + ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access, + inherit_handle_ipc, answer); + + return code; +} + HANDLE WINAPI TargetCreateEventW(CreateEventWFunction orig_CreateEvent, LPSECURITY_ATTRIBUTES security_attributes, - BOOL manual_reset, BOOL initial_state, + BOOL manual_reset, + BOOL initial_state, LPCWSTR name) { // Check if the process can create it first. HANDLE handle = orig_CreateEvent(security_attributes, manual_reset, initial_state, name); - DWORD original_error = ::GetLastError(); - if (NULL != handle) + if (handle || !name) return handle; + DWORD original_error = ::GetLastError(); + // We don't trust that the IPC can work this early. if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) return NULL; - do { - if (security_attributes) - break; + CrossCallReturn answer = {0}; + ResultCode code = ProxyCreateEvent(name, initial_state, manual_reset, + &answer); - void* memory = GetGlobalIPCMemory(); - if (NULL == memory) - break; + if (code == SBOX_ALL_OK) { + ::SetLastError(answer.win32_result); + return answer.handle; + } + ::SetLastError(original_error); + return NULL; +} - CountedParameterSet<NameBased> params; - params[NameBased::NAME] = ParamPickerMake(name); +HANDLE WINAPI TargetCreateEventA(CreateEventAFunction orig_CreateEvent, + LPSECURITY_ATTRIBUTES security_attributes, + BOOL manual_reset, + BOOL initial_state, + LPCSTR name) { + // Check if the process can create it first. + HANDLE handle = orig_CreateEvent(security_attributes, manual_reset, + initial_state, name); + if (handle || !name) + return handle; - if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase())) - break; + DWORD original_error = ::GetLastError(); - SharedMemIPCClient ipc(memory); - CrossCallReturn answer = {0}; - ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, manual_reset, - initial_state, &answer); + // We don't trust that the IPC can work this early. + if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) + return NULL; + + UNICODE_STRING* wide_name = AnsiToUnicode(name); + if (!wide_name) + return NULL; - if (SBOX_ALL_OK != code) - break; + CrossCallReturn answer = {0}; + ResultCode code = ProxyCreateEvent(wide_name->Buffer, initial_state, + manual_reset, &answer); + operator delete(wide_name, NT_ALLOC); + if (code == SBOX_ALL_OK) { ::SetLastError(answer.win32_result); return answer.handle; - } while (false); - + } ::SetLastError(original_error); return NULL; } @@ -63,43 +124,60 @@ HANDLE WINAPI TargetCreateEventW(CreateEventWFunction orig_CreateEvent, // Interception of OpenEventW on the child process. // It should never be called directly HANDLE WINAPI TargetOpenEventW(OpenEventWFunction orig_OpenEvent, - ACCESS_MASK desired_access, BOOL inherit_handle, + ACCESS_MASK desired_access, + BOOL inherit_handle, LPCWSTR name) { // Check if the process can open it first. HANDLE handle = orig_OpenEvent(desired_access, inherit_handle, name); - DWORD original_error = ::GetLastError(); - if (NULL != handle) + if (handle || !name) return handle; + DWORD original_error = ::GetLastError(); + // We don't trust that the IPC can work this early. if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) return NULL; - do { - void* memory = GetGlobalIPCMemory(); - if (NULL == memory) - break; + CrossCallReturn answer = {0}; - uint32 inherit_handle_ipc = inherit_handle; - CountedParameterSet<OpenEventParams> params; - params[OpenEventParams::NAME] = ParamPickerMake(name); - params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access); + ResultCode code = ProxyOpenEvent(name, desired_access, inherit_handle, + &answer); + if (code == SBOX_ALL_OK) { + ::SetLastError(answer.win32_result); + return answer.handle; + } + ::SetLastError(original_error); + return NULL; +} - if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase())) - break; +HANDLE WINAPI TargetOpenEventA(OpenEventAFunction orig_OpenEvent, + ACCESS_MASK desired_access, + BOOL inherit_handle, + LPCSTR name) { + // Check if the process can open it first. + HANDLE handle = orig_OpenEvent(desired_access, inherit_handle, name); + if (handle || !name) + return handle; - SharedMemIPCClient ipc(memory); - CrossCallReturn answer = {0}; - ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access, - inherit_handle_ipc, &answer); + DWORD original_error = ::GetLastError(); - if (SBOX_ALL_OK != code) - break; + // We don't trust that the IPC can work this early. + if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) + return NULL; + + UNICODE_STRING* wide_name = AnsiToUnicode(name); + if (!wide_name) + return NULL; + CrossCallReturn answer = {0}; + ResultCode code = ProxyOpenEvent(wide_name->Buffer, desired_access, + inherit_handle, &answer); + operator delete(wide_name, NT_ALLOC); + + if (code == SBOX_ALL_OK) { ::SetLastError(answer.win32_result); return answer.handle; - } while (false); - + } ::SetLastError(original_error); return NULL; } diff --git a/sandbox/win/src/sync_interception.h b/sandbox/win/src/sync_interception.h index 6c5c46e..c1a8893 100644 --- a/sandbox/win/src/sync_interception.h +++ b/sandbox/win/src/sync_interception.h @@ -18,21 +18,49 @@ typedef HANDLE (WINAPI *CreateEventWFunction) ( BOOL bInheritHandle, LPCWSTR lpName); +typedef HANDLE (WINAPI *CreateEventAFunction) ( + LPSECURITY_ATTRIBUTES lpEventAttributes, + DWORD dwDesiredAccess, + BOOL bInheritHandle, + LPCSTR lpName); + typedef HANDLE (WINAPI *OpenEventWFunction) ( BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName); -// Interception of CreateEvent on the child process. +typedef HANDLE (WINAPI *OpenEventAFunction) ( + BOOL bManualReset, + BOOL bInitialState, + LPCSTR lpName); + +// Interceptors for CreateEventW/A SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventW( CreateEventWFunction orig_CreateEvent, - LPSECURITY_ATTRIBUTES security_attributes, BOOL manual_reset, - BOOL initial_state, LPCWSTR name); + LPSECURITY_ATTRIBUTES security_attributes, + BOOL manual_reset, + BOOL initial_state, + LPCWSTR name); -// Interception of OpenEvent on the child process. +SANDBOX_INTERCEPT HANDLE WINAPI TargetCreateEventA( + CreateEventAFunction orig_CreateEvent, + LPSECURITY_ATTRIBUTES security_attributes, + BOOL manual_reset, + BOOL initial_state, + LPCSTR name); + +// Interceptors for OpenEventW/A SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventW( - OpenEventWFunction orig_OpenEvent, ACCESS_MASK desired_access, - BOOL inherit_handle, LPCWSTR name); + OpenEventWFunction orig_OpenEvent, + ACCESS_MASK desired_access, + BOOL inherit_handle, + LPCWSTR name); + +SANDBOX_INTERCEPT HANDLE WINAPI TargetOpenEventA( + OpenEventAFunction orig_OpenEvent, + ACCESS_MASK desired_access, + BOOL inherit_handle, + LPCSTR name); } // extern "C" |