1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/policy_broker.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,115 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include <map> 1.9 + 1.10 +#include "sandbox/win/src/policy_broker.h" 1.11 + 1.12 +#include "base/logging.h" 1.13 +#include "base/win/pe_image.h" 1.14 +#include "base/win/windows_version.h" 1.15 +#include "sandbox/win/src/interception.h" 1.16 +#include "sandbox/win/src/interceptors.h" 1.17 +#include "sandbox/win/src/policy_target.h" 1.18 +#include "sandbox/win/src/process_thread_interception.h" 1.19 +#include "sandbox/win/src/sandbox.h" 1.20 +#include "sandbox/win/src/sandbox_nt_types.h" 1.21 +#include "sandbox/win/src/sandbox_types.h" 1.22 +#include "sandbox/win/src/target_process.h" 1.23 + 1.24 +// This code executes on the broker side, as a callback from the policy on the 1.25 +// target side (the child). 1.26 + 1.27 +namespace sandbox { 1.28 + 1.29 +// This is the list of all imported symbols from ntdll.dll. 1.30 +SANDBOX_INTERCEPT NtExports g_nt; 1.31 + 1.32 +#define INIT_GLOBAL_NT(member) \ 1.33 + g_nt.member = reinterpret_cast<Nt##member##Function>( \ 1.34 + ntdll_image.GetProcAddress("Nt" #member)); \ 1.35 + if (NULL == g_nt.member) \ 1.36 + return false 1.37 + 1.38 +#define INIT_GLOBAL_RTL(member) \ 1.39 + g_nt.member = reinterpret_cast<member##Function>( \ 1.40 + ntdll_image.GetProcAddress(#member)); \ 1.41 + if (NULL == g_nt.member) \ 1.42 + return false 1.43 + 1.44 +bool SetupNtdllImports(TargetProcess *child) { 1.45 + HMODULE ntdll = ::GetModuleHandle(kNtdllName); 1.46 + base::win::PEImage ntdll_image(ntdll); 1.47 + 1.48 + // Bypass purify's interception. 1.49 + wchar_t* loader_get = reinterpret_cast<wchar_t*>( 1.50 + ntdll_image.GetProcAddress("LdrGetDllHandle")); 1.51 + if (loader_get) { 1.52 + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 1.53 + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 1.54 + loader_get, &ntdll); 1.55 + } 1.56 + 1.57 + INIT_GLOBAL_NT(AllocateVirtualMemory); 1.58 + INIT_GLOBAL_NT(Close); 1.59 + INIT_GLOBAL_NT(DuplicateObject); 1.60 + INIT_GLOBAL_NT(FreeVirtualMemory); 1.61 + INIT_GLOBAL_NT(MapViewOfSection); 1.62 + INIT_GLOBAL_NT(ProtectVirtualMemory); 1.63 + INIT_GLOBAL_NT(QueryInformationProcess); 1.64 + INIT_GLOBAL_NT(QueryObject); 1.65 + INIT_GLOBAL_NT(QuerySection); 1.66 + INIT_GLOBAL_NT(QueryVirtualMemory); 1.67 + INIT_GLOBAL_NT(UnmapViewOfSection); 1.68 + 1.69 + INIT_GLOBAL_RTL(RtlAllocateHeap); 1.70 + INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString); 1.71 + INIT_GLOBAL_RTL(RtlCompareUnicodeString); 1.72 + INIT_GLOBAL_RTL(RtlCreateHeap); 1.73 + INIT_GLOBAL_RTL(RtlCreateUserThread); 1.74 + INIT_GLOBAL_RTL(RtlDestroyHeap); 1.75 + INIT_GLOBAL_RTL(RtlFreeHeap); 1.76 + INIT_GLOBAL_RTL(_strnicmp); 1.77 + INIT_GLOBAL_RTL(strlen); 1.78 + INIT_GLOBAL_RTL(wcslen); 1.79 + 1.80 +#ifndef NDEBUG 1.81 + // Verify that the structure is fully initialized. 1.82 + for (size_t i = 0; i < sizeof(g_nt)/sizeof(void*); i++) 1.83 + DCHECK(reinterpret_cast<char**>(&g_nt)[i]); 1.84 +#endif 1.85 + return (SBOX_ALL_OK == child->TransferVariable("g_nt", &g_nt, sizeof(g_nt))); 1.86 +} 1.87 + 1.88 +#undef INIT_GLOBAL_NT 1.89 +#undef INIT_GLOBAL_RTL 1.90 + 1.91 +bool SetupBasicInterceptions(InterceptionManager* manager) { 1.92 + // Interceptions provided by process_thread_policy, without actual policy. 1.93 + if (!INTERCEPT_NT(manager, NtOpenThread, OPEN_TREAD_ID, 20) || 1.94 + !INTERCEPT_NT(manager, NtOpenProcess, OPEN_PROCESS_ID, 20) || 1.95 + !INTERCEPT_NT(manager, NtOpenProcessToken, OPEN_PROCESS_TOKEN_ID, 16)) 1.96 + return false; 1.97 + 1.98 + // Interceptions with neither policy nor IPC. 1.99 + if (!INTERCEPT_NT(manager, NtSetInformationThread, SET_INFORMATION_THREAD_ID, 1.100 + 20) || 1.101 + !INTERCEPT_NT(manager, NtOpenThreadToken, OPEN_THREAD_TOKEN_ID, 20)) 1.102 + return false; 1.103 + 1.104 + if (base::win::GetVersion() >= base::win::VERSION_XP) { 1.105 + // Bug 27218: We don't have dispatch for some x64 syscalls. 1.106 + // This one is also provided by process_thread_policy. 1.107 + if (!INTERCEPT_NT(manager, NtOpenProcessTokenEx, OPEN_PROCESS_TOKEN_EX_ID, 1.108 + 20)) 1.109 + return false; 1.110 + 1.111 + return INTERCEPT_NT(manager, NtOpenThreadTokenEx, OPEN_THREAD_TOKEN_EX_ID, 1.112 + 24); 1.113 + } 1.114 + 1.115 + return true; 1.116 +} 1.117 + 1.118 +} // namespace sandbox