diff options
Diffstat (limited to 'sandbox/win/src/target_services.cc')
-rw-r--r-- | sandbox/win/src/target_services.cc | 209 |
1 files changed, 0 insertions, 209 deletions
diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc deleted file mode 100644 index 7c0afc210a..0000000000 --- a/sandbox/win/src/target_services.cc +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (c) 2012 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/target_services.h" - -#include <new> - -#include <process.h> - -#include "base/basictypes.h" -#include "base/win/windows_version.h" -#include "sandbox/win/src/crosscall_client.h" -#include "sandbox/win/src/handle_closer_agent.h" -#include "sandbox/win/src/handle_interception.h" -#include "sandbox/win/src/ipc_tags.h" -#include "sandbox/win/src/process_mitigations.h" -#include "sandbox/win/src/restricted_token_utils.h" -#include "sandbox/win/src/sandbox.h" -#include "sandbox/win/src/sandbox_types.h" -#include "sandbox/win/src/sharedmem_ipc_client.h" -#include "sandbox/win/src/sandbox_nt_util.h" - -namespace { - -// Flushing a cached key is triggered by just opening the key and closing the -// resulting handle. RegDisablePredefinedCache() is the documented way to flush -// HKCU so do not use it with this function. -bool FlushRegKey(HKEY root) { - HKEY key; - if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) { - if (ERROR_SUCCESS != ::RegCloseKey(key)) - return false; - } - return true; -} - -// This function forces advapi32.dll to release some internally cached handles -// that were made during calls to RegOpenkey and RegOpenKeyEx if it is called -// with a more restrictive token. Returns true if the flushing is succesful -// although this behavior is undocumented and there is no guarantee that in -// fact this will happen in future versions of windows. -bool FlushCachedRegHandles() { - return (FlushRegKey(HKEY_LOCAL_MACHINE) && - FlushRegKey(HKEY_CLASSES_ROOT) && - FlushRegKey(HKEY_USERS)); -} - -// Checks if we have handle entries pending and runs the closer. -bool CloseOpenHandles() { - if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) { - sandbox::HandleCloserAgent handle_closer; - - handle_closer.InitializeHandlesToClose(); - if (!handle_closer.CloseHandles()) - return false; - } - - return true; -} - -// Used as storage for g_target_services, because other allocation facilities -// are not available early. We can't use a regular function static because on -// VS2015, because the CRT tries to acquire a lock to guard initialization, but -// this code runs before the CRT is initialized. -char g_target_services_memory[sizeof(sandbox::TargetServicesBase)]; -sandbox::TargetServicesBase* g_target_services = nullptr; - -} // namespace - -namespace sandbox { - -SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level = - INTEGRITY_LEVEL_LAST; -SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations = 0; - -TargetServicesBase::TargetServicesBase() { -} - -ResultCode TargetServicesBase::Init() { - process_state_.SetInitCalled(); - return SBOX_ALL_OK; -} - -// Failure here is a breach of security so the process is terminated. -void TargetServicesBase::LowerToken() { - if (ERROR_SUCCESS != - SetProcessIntegrityLevel(g_shared_delayed_integrity_level)) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY); - process_state_.SetRevertedToSelf(); - // If the client code as called RegOpenKey, advapi32.dll has cached some - // handles. The following code gets rid of them. - if (!::RevertToSelf()) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN); - if (!FlushCachedRegHandles()) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES); - if (ERROR_SUCCESS != ::RegDisablePredefinedCache()) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE); - if (!CloseOpenHandles()) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES); - // Enabling mitigations must happen last otherwise handle closing breaks - if (g_shared_delayed_mitigations && - !ApplyProcessMitigationsToCurrentProcess(g_shared_delayed_mitigations)) - ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_MITIGATION); -} - -ProcessState* TargetServicesBase::GetState() { - return &process_state_; -} - -TargetServicesBase* TargetServicesBase::GetInstance() { - // Leak on purpose TargetServicesBase. - if (!g_target_services) - g_target_services = new (g_target_services_memory) TargetServicesBase; - return g_target_services; -} - -// The broker services a 'test' IPC service with the IPC_PING_TAG tag. -bool TargetServicesBase::TestIPCPing(int version) { - void* memory = GetGlobalIPCMemory(); - if (NULL == memory) { - return false; - } - SharedMemIPCClient ipc(memory); - CrossCallReturn answer = {0}; - - if (1 == version) { - uint32 tick1 = ::GetTickCount(); - uint32 cookie = 717115; - ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer); - - if (SBOX_ALL_OK != code) { - return false; - } - // We should get two extended returns values from the IPC, one is the - // tick count on the broker and the other is the cookie times two. - if ((answer.extended_count != 2)) { - return false; - } - // We test the first extended answer to be within the bounds of the tick - // count only if there was no tick count wraparound. - uint32 tick2 = ::GetTickCount(); - if (tick2 >= tick1) { - if ((answer.extended[0].unsigned_int < tick1) || - (answer.extended[0].unsigned_int > tick2)) { - return false; - } - } - - if (answer.extended[1].unsigned_int != cookie * 2) { - return false; - } - } else if (2 == version) { - uint32 cookie = 717111; - InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie)); - ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer); - - if (SBOX_ALL_OK != code) { - return false; - } - if (cookie != 717111 * 3) { - return false; - } - } else { - return false; - } - return true; -} - -ProcessState::ProcessState() : process_state_(0) { -} - -bool ProcessState::IsKernel32Loaded() const { - return process_state_ != 0; -} - -bool ProcessState::InitCalled() const { - return process_state_ > 1; -} - -bool ProcessState::RevertedToSelf() const { - return process_state_ > 2; -} - -void ProcessState::SetKernel32Loaded() { - if (!process_state_) - process_state_ = 1; -} - -void ProcessState::SetInitCalled() { - if (process_state_ < 2) - process_state_ = 2; -} - -void ProcessState::SetRevertedToSelf() { - if (process_state_ < 3) - process_state_ = 3; -} - -ResultCode TargetServicesBase::DuplicateHandle(HANDLE source_handle, - DWORD target_process_id, - HANDLE* target_handle, - DWORD desired_access, - DWORD options) { - return sandbox::DuplicateHandleProxy(source_handle, target_process_id, - target_handle, desired_access, options); -} - -} // namespace sandbox |