15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_target.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_client.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/ipc_tags.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_processor.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_low_level.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_params.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_factory.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sharedmem_ipc_client.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/target_services.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handle for our private heap. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void* g_heap; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the list of all imported symbols from ntdll.dll. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT NtExports g_nt; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Policy data. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern void* volatile g_shared_policy_memory; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT size_t g_shared_policy_size; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QueryBroker(int ipc_id, CountedParameterSetBase* params) { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NT(static_cast<size_t>(ipc_id) < kMaxServiceCount); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NT(g_shared_policy_memory); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NT(g_shared_policy_size > 0); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<size_t>(ipc_id) >= kMaxServiceCount) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyGlobal* global_policy = 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<PolicyGlobal*>(g_shared_policy_memory); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!global_policy->entry[ipc_id]) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyBuffer* policy = reinterpret_cast<PolicyBuffer*>( 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<char*>(g_shared_policy_memory) + 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<size_t>(global_policy->entry[ipc_id])); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((reinterpret_cast<size_t>(global_policy->entry[ipc_id]) > 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) global_policy->data_size) || 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (g_shared_policy_size < global_policy->data_size)) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED_NT(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < params->count; i++) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!params->parameters[i].IsValid()) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED_NT(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyProcessor processor(policy); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyResult result = processor.Evaluate(kShortEval, params->parameters, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->count); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NT(POLICY_ERROR != result); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return POLICY_MATCH == result && ASK_BROKER == processor.GetAction(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ----------------------------------------------------------------------- 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Hooks NtSetInformationThread to block RevertToSelf from being 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// called before the actual call to LowerToken. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtSetInformationThread( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NtSetInformationThreadFunction orig_SetInformationThread, HANDLE thread, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NT_THREAD_INFORMATION_CLASS thread_info_class, PVOID thread_information, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG thread_information_bytes) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ThreadImpersonationToken != thread_info_class) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!thread_information) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE token; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizeof(token) > thread_information_bytes) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NTSTATUS ret = CopyData(&token, thread_information, sizeof(token)); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NT_SUCCESS(ret) || NULL != token) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a revert to self. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return STATUS_SUCCESS; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return orig_SetInformationThread(thread, thread_info_class, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_information, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_information_bytes); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Hooks NtOpenThreadToken to force the open_as_self parameter to be set to 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FALSE if we are still running with the impersonation token. open_as_self set 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to TRUE means that the token will be open using the process token instead of 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the impersonation token. This is bad because the process token does not have 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// access to open the thread token. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtOpenThreadToken( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NtOpenThreadTokenFunction orig_OpenThreadToken, HANDLE thread, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCESS_MASK desired_access, BOOLEAN open_as_self, PHANDLE token) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_as_self = FALSE; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return orig_OpenThreadToken(thread, desired_access, open_as_self, token); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See comment for TargetNtOpenThreadToken 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NTSTATUS WINAPI TargetNtOpenThreadTokenEx( 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NtOpenThreadTokenExFunction orig_OpenThreadTokenEx, HANDLE thread, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCESS_MASK desired_access, BOOLEAN open_as_self, ULONG handle_attributes, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PHANDLE token) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_as_self = FALSE; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return orig_OpenThreadTokenEx(thread, desired_access, open_as_self, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_attributes, token); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 128