1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "sandbox/win/src/policy_target.h" 6 7 #include "sandbox/win/src/crosscall_client.h" 8 #include "sandbox/win/src/ipc_tags.h" 9 #include "sandbox/win/src/policy_engine_processor.h" 10 #include "sandbox/win/src/policy_low_level.h" 11 #include "sandbox/win/src/policy_params.h" 12 #include "sandbox/win/src/sandbox_factory.h" 13 #include "sandbox/win/src/sandbox_nt_util.h" 14 #include "sandbox/win/src/sharedmem_ipc_client.h" 15 #include "sandbox/win/src/target_services.h" 16 17 namespace sandbox { 18 19 // Handle for our private heap. 20 extern void* g_heap; 21 22 // This is the list of all imported symbols from ntdll.dll. 23 SANDBOX_INTERCEPT NtExports g_nt; 24 25 // Policy data. 26 extern void* volatile g_shared_policy_memory; 27 SANDBOX_INTERCEPT size_t g_shared_policy_size; 28 29 bool QueryBroker(int ipc_id, CountedParameterSetBase* params) { 30 DCHECK_NT(static_cast<size_t>(ipc_id) < kMaxServiceCount); 31 DCHECK_NT(g_shared_policy_memory); 32 DCHECK_NT(g_shared_policy_size > 0); 33 34 if (static_cast<size_t>(ipc_id) >= kMaxServiceCount) 35 return false; 36 37 PolicyGlobal* global_policy = 38 reinterpret_cast<PolicyGlobal*>(g_shared_policy_memory); 39 40 if (!global_policy->entry[ipc_id]) 41 return false; 42 43 PolicyBuffer* policy = reinterpret_cast<PolicyBuffer*>( 44 reinterpret_cast<char*>(g_shared_policy_memory) + 45 reinterpret_cast<size_t>(global_policy->entry[ipc_id])); 46 47 if ((reinterpret_cast<size_t>(global_policy->entry[ipc_id]) > 48 global_policy->data_size) || 49 (g_shared_policy_size < global_policy->data_size)) { 50 NOTREACHED_NT(); 51 return false; 52 } 53 54 for (int i = 0; i < params->count; i++) { 55 if (!params->parameters[i].IsValid()) { 56 NOTREACHED_NT(); 57 return false; 58 } 59 } 60 61 PolicyProcessor processor(policy); 62 PolicyResult result = processor.Evaluate(kShortEval, params->parameters, 63 params->count); 64 DCHECK_NT(POLICY_ERROR != result); 65 66 return POLICY_MATCH == result && ASK_BROKER == processor.GetAction(); 67 } 68 69 // ----------------------------------------------------------------------- 70 71 // Hooks NtSetInformationThread to block RevertToSelf from being 72 // called before the actual call to LowerToken. 73 NTSTATUS WINAPI TargetNtSetInformationThread( 74 NtSetInformationThreadFunction orig_SetInformationThread, HANDLE thread, 75 NT_THREAD_INFORMATION_CLASS thread_info_class, PVOID thread_information, 76 ULONG thread_information_bytes) { 77 do { 78 if (SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 79 break; 80 if (ThreadImpersonationToken != thread_info_class) 81 break; 82 if (!thread_information) 83 break; 84 HANDLE token; 85 if (sizeof(token) > thread_information_bytes) 86 break; 87 88 NTSTATUS ret = CopyData(&token, thread_information, sizeof(token)); 89 if (!NT_SUCCESS(ret) || NULL != token) 90 break; 91 92 // This is a revert to self. 93 return STATUS_SUCCESS; 94 } while (false); 95 96 return orig_SetInformationThread(thread, thread_info_class, 97 thread_information, 98 thread_information_bytes); 99 } 100 101 // Hooks NtOpenThreadToken to force the open_as_self parameter to be set to 102 // FALSE if we are still running with the impersonation token. open_as_self set 103 // to TRUE means that the token will be open using the process token instead of 104 // the impersonation token. This is bad because the process token does not have 105 // access to open the thread token. 106 NTSTATUS WINAPI TargetNtOpenThreadToken( 107 NtOpenThreadTokenFunction orig_OpenThreadToken, HANDLE thread, 108 ACCESS_MASK desired_access, BOOLEAN open_as_self, PHANDLE token) { 109 if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 110 open_as_self = FALSE; 111 112 return orig_OpenThreadToken(thread, desired_access, open_as_self, token); 113 } 114 115 // See comment for TargetNtOpenThreadToken 116 NTSTATUS WINAPI TargetNtOpenThreadTokenEx( 117 NtOpenThreadTokenExFunction orig_OpenThreadTokenEx, HANDLE thread, 118 ACCESS_MASK desired_access, BOOLEAN open_as_self, ULONG handle_attributes, 119 PHANDLE token) { 120 if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf()) 121 open_as_self = FALSE; 122 123 return orig_OpenThreadTokenEx(thread, desired_access, open_as_self, 124 handle_attributes, token); 125 } 126 127 } // namespace sandbox 128