| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/src/sandbox_policy_base.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 8 #include "base/callback.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "sandbox/src/filesystem_dispatcher.h" | |
| 11 #include "sandbox/src/filesystem_policy.h" | |
| 12 #include "sandbox/src/handle_dispatcher.h" | |
| 13 #include "sandbox/src/handle_policy.h" | |
| 14 #include "sandbox/src/job.h" | |
| 15 #include "sandbox/src/interception.h" | |
| 16 #include "sandbox/src/named_pipe_dispatcher.h" | |
| 17 #include "sandbox/src/named_pipe_policy.h" | |
| 18 #include "sandbox/src/policy_broker.h" | |
| 19 #include "sandbox/src/policy_engine_processor.h" | |
| 20 #include "sandbox/src/policy_low_level.h" | |
| 21 #include "sandbox/src/process_thread_dispatcher.h" | |
| 22 #include "sandbox/src/process_thread_policy.h" | |
| 23 #include "sandbox/src/registry_dispatcher.h" | |
| 24 #include "sandbox/src/registry_policy.h" | |
| 25 #include "sandbox/src/restricted_token_utils.h" | |
| 26 #include "sandbox/src/sandbox_policy.h" | |
| 27 #include "sandbox/src/sync_dispatcher.h" | |
| 28 #include "sandbox/src/sync_policy.h" | |
| 29 #include "sandbox/src/target_process.h" | |
| 30 #include "sandbox/src/window.h" | |
| 31 | |
| 32 namespace { | |
| 33 // The standard windows size for one memory page. | |
| 34 const size_t kOneMemPage = 4096; | |
| 35 // The IPC and Policy shared memory sizes. | |
| 36 const size_t kIPCMemSize = kOneMemPage * 2; | |
| 37 const size_t kPolMemSize = kOneMemPage * 14; | |
| 38 | |
| 39 // Helper function to allocate space (on the heap) for policy. | |
| 40 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() { | |
| 41 const size_t kTotalPolicySz = kPolMemSize; | |
| 42 char* mem = new char[kTotalPolicySz]; | |
| 43 DCHECK(mem); | |
| 44 memset(mem, 0, kTotalPolicySz); | |
| 45 sandbox::PolicyGlobal* policy = reinterpret_cast<sandbox::PolicyGlobal*>(mem); | |
| 46 policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal); | |
| 47 return policy; | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 namespace sandbox { | |
| 52 | |
| 53 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; | |
| 54 | |
| 55 // Initializes static members. | |
| 56 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; | |
| 57 HDESK PolicyBase::alternate_desktop_handle_ = NULL; | |
| 58 | |
| 59 PolicyBase::PolicyBase() | |
| 60 : ref_count(1), | |
| 61 lockdown_level_(USER_LOCKDOWN), | |
| 62 initial_level_(USER_LOCKDOWN), | |
| 63 job_level_(JOB_LOCKDOWN), | |
| 64 ui_exceptions_(0), | |
| 65 use_alternate_desktop_(false), | |
| 66 use_alternate_winstation_(false), | |
| 67 file_system_init_(false), | |
| 68 relaxed_interceptions_(true), | |
| 69 integrity_level_(INTEGRITY_LEVEL_LAST), | |
| 70 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), | |
| 71 policy_maker_(NULL), | |
| 72 policy_(NULL) { | |
| 73 ::InitializeCriticalSection(&lock_); | |
| 74 // Initialize the IPC dispatcher array. | |
| 75 memset(&ipc_targets_, NULL, sizeof(ipc_targets_)); | |
| 76 Dispatcher* dispatcher = NULL; | |
| 77 | |
| 78 dispatcher = new FilesystemDispatcher(this); | |
| 79 ipc_targets_[IPC_NTCREATEFILE_TAG] = dispatcher; | |
| 80 ipc_targets_[IPC_NTOPENFILE_TAG] = dispatcher; | |
| 81 ipc_targets_[IPC_NTSETINFO_RENAME_TAG] = dispatcher; | |
| 82 ipc_targets_[IPC_NTQUERYATTRIBUTESFILE_TAG] = dispatcher; | |
| 83 ipc_targets_[IPC_NTQUERYFULLATTRIBUTESFILE_TAG] = dispatcher; | |
| 84 | |
| 85 dispatcher = new NamedPipeDispatcher(this); | |
| 86 ipc_targets_[IPC_CREATENAMEDPIPEW_TAG] = dispatcher; | |
| 87 | |
| 88 dispatcher = new ThreadProcessDispatcher(this); | |
| 89 ipc_targets_[IPC_NTOPENTHREAD_TAG] = dispatcher; | |
| 90 ipc_targets_[IPC_NTOPENPROCESS_TAG] = dispatcher; | |
| 91 ipc_targets_[IPC_CREATEPROCESSW_TAG] = dispatcher; | |
| 92 ipc_targets_[IPC_NTOPENPROCESSTOKEN_TAG] = dispatcher; | |
| 93 ipc_targets_[IPC_NTOPENPROCESSTOKENEX_TAG] = dispatcher; | |
| 94 | |
| 95 dispatcher = new SyncDispatcher(this); | |
| 96 ipc_targets_[IPC_CREATEEVENT_TAG] = dispatcher; | |
| 97 ipc_targets_[IPC_OPENEVENT_TAG] = dispatcher; | |
| 98 | |
| 99 dispatcher = new RegistryDispatcher(this); | |
| 100 ipc_targets_[IPC_NTCREATEKEY_TAG] = dispatcher; | |
| 101 ipc_targets_[IPC_NTOPENKEY_TAG] = dispatcher; | |
| 102 | |
| 103 dispatcher = new HandleDispatcher(this); | |
| 104 ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG] = dispatcher; | |
| 105 } | |
| 106 | |
| 107 PolicyBase::~PolicyBase() { | |
| 108 TargetSet::iterator it; | |
| 109 for (it = targets_.begin(); it != targets_.end(); ++it) { | |
| 110 TargetProcess* target = (*it); | |
| 111 delete target; | |
| 112 } | |
| 113 delete ipc_targets_[IPC_NTCREATEFILE_TAG]; | |
| 114 delete ipc_targets_[IPC_CREATENAMEDPIPEW_TAG]; | |
| 115 delete ipc_targets_[IPC_NTOPENTHREAD_TAG]; | |
| 116 delete ipc_targets_[IPC_CREATEEVENT_TAG]; | |
| 117 delete ipc_targets_[IPC_NTCREATEKEY_TAG]; | |
| 118 delete ipc_targets_[IPC_DUPLICATEHANDLEPROXY_TAG]; | |
| 119 delete policy_maker_; | |
| 120 delete policy_; | |
| 121 ::DeleteCriticalSection(&lock_); | |
| 122 } | |
| 123 | |
| 124 void PolicyBase::AddRef() { | |
| 125 ::InterlockedIncrement(&ref_count); | |
| 126 } | |
| 127 | |
| 128 void PolicyBase::Release() { | |
| 129 if (0 == ::InterlockedDecrement(&ref_count)) | |
| 130 delete this; | |
| 131 } | |
| 132 | |
| 133 ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) { | |
| 134 if (initial < lockdown) { | |
| 135 return SBOX_ERROR_BAD_PARAMS; | |
| 136 } | |
| 137 initial_level_ = initial; | |
| 138 lockdown_level_ = lockdown; | |
| 139 return SBOX_ALL_OK; | |
| 140 } | |
| 141 | |
| 142 ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) { | |
| 143 job_level_ = job_level; | |
| 144 ui_exceptions_ = ui_exceptions; | |
| 145 return SBOX_ALL_OK; | |
| 146 } | |
| 147 | |
| 148 ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) { | |
| 149 use_alternate_desktop_ = true; | |
| 150 use_alternate_winstation_ = alternate_winstation; | |
| 151 return CreateAlternateDesktop(alternate_winstation); | |
| 152 } | |
| 153 | |
| 154 std::wstring PolicyBase::GetAlternateDesktop() const { | |
| 155 // No alternate desktop or winstation. Return an empty string. | |
| 156 if (!use_alternate_desktop_ && !use_alternate_winstation_) { | |
| 157 return std::wstring(); | |
| 158 } | |
| 159 | |
| 160 // The desktop and winstation should have been created by now. | |
| 161 // If we hit this scenario, it means that the user ignored the failure | |
| 162 // during SetAlternateDesktop, so we ignore it here too. | |
| 163 if (use_alternate_desktop_ && !alternate_desktop_handle_) { | |
| 164 return std::wstring(); | |
| 165 } | |
| 166 if (use_alternate_winstation_ && (!alternate_desktop_handle_ || | |
| 167 !alternate_winstation_handle_)) { | |
| 168 return std::wstring(); | |
| 169 } | |
| 170 | |
| 171 return GetFullDesktopName(alternate_winstation_handle_, | |
| 172 alternate_desktop_handle_); | |
| 173 } | |
| 174 | |
| 175 ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) { | |
| 176 if (alternate_winstation) { | |
| 177 // Previously called with alternate_winstation = false? | |
| 178 if (!alternate_winstation_handle_ && alternate_desktop_handle_) | |
| 179 return SBOX_ERROR_UNSUPPORTED; | |
| 180 | |
| 181 // Check if it's already created. | |
| 182 if (alternate_winstation_handle_ && alternate_desktop_handle_) | |
| 183 return SBOX_ALL_OK; | |
| 184 | |
| 185 DCHECK(!alternate_winstation_handle_); | |
| 186 // Create the window station. | |
| 187 ResultCode result = CreateAltWindowStation(&alternate_winstation_handle_); | |
| 188 if (SBOX_ALL_OK != result) | |
| 189 return result; | |
| 190 | |
| 191 // Verify that everything is fine. | |
| 192 if (!alternate_winstation_handle_ || | |
| 193 GetWindowObjectName(alternate_winstation_handle_).empty()) | |
| 194 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; | |
| 195 | |
| 196 // Create the destkop. | |
| 197 result = CreateAltDesktop(alternate_winstation_handle_, | |
| 198 &alternate_desktop_handle_); | |
| 199 if (SBOX_ALL_OK != result) | |
| 200 return result; | |
| 201 | |
| 202 // Verify that everything is fine. | |
| 203 if (!alternate_desktop_handle_ || | |
| 204 GetWindowObjectName(alternate_desktop_handle_).empty()) | |
| 205 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; | |
| 206 } else { | |
| 207 // Previously called with alternate_winstation = true? | |
| 208 if (alternate_winstation_handle_) | |
| 209 return SBOX_ERROR_UNSUPPORTED; | |
| 210 | |
| 211 // Check if it already exists. | |
| 212 if (alternate_desktop_handle_) | |
| 213 return SBOX_ALL_OK; | |
| 214 | |
| 215 // Create the destkop. | |
| 216 ResultCode result = CreateAltDesktop(NULL, &alternate_desktop_handle_); | |
| 217 if (SBOX_ALL_OK != result) | |
| 218 return result; | |
| 219 | |
| 220 // Verify that everything is fine. | |
| 221 if (!alternate_desktop_handle_ || | |
| 222 GetWindowObjectName(alternate_desktop_handle_).empty()) | |
| 223 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; | |
| 224 } | |
| 225 | |
| 226 return SBOX_ALL_OK; | |
| 227 } | |
| 228 | |
| 229 void PolicyBase::DestroyAlternateDesktop() { | |
| 230 if (alternate_desktop_handle_) { | |
| 231 ::CloseDesktop(alternate_desktop_handle_); | |
| 232 alternate_desktop_handle_ = NULL; | |
| 233 } | |
| 234 | |
| 235 if (alternate_winstation_handle_) { | |
| 236 ::CloseWindowStation(alternate_winstation_handle_); | |
| 237 alternate_winstation_handle_ = NULL; | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) { | |
| 242 integrity_level_ = integrity_level; | |
| 243 return SBOX_ALL_OK; | |
| 244 } | |
| 245 | |
| 246 ResultCode PolicyBase::SetDelayedIntegrityLevel( | |
| 247 IntegrityLevel integrity_level) { | |
| 248 delayed_integrity_level_ = integrity_level; | |
| 249 return SBOX_ALL_OK; | |
| 250 } | |
| 251 | |
| 252 void PolicyBase::SetStrictInterceptions() { | |
| 253 relaxed_interceptions_ = false; | |
| 254 } | |
| 255 | |
| 256 ResultCode PolicyBase::AddRule(SubSystem subsystem, Semantics semantics, | |
| 257 const wchar_t* pattern) { | |
| 258 if (NULL == policy_) { | |
| 259 policy_ = MakeBrokerPolicyMemory(); | |
| 260 DCHECK(policy_); | |
| 261 policy_maker_ = new LowLevelPolicy(policy_); | |
| 262 DCHECK(policy_maker_); | |
| 263 } | |
| 264 | |
| 265 switch (subsystem) { | |
| 266 case SUBSYS_FILES: { | |
| 267 if (!file_system_init_) { | |
| 268 if (!FileSystemPolicy::SetInitialRules(policy_maker_)) | |
| 269 return SBOX_ERROR_BAD_PARAMS; | |
| 270 file_system_init_ = true; | |
| 271 } | |
| 272 if (!FileSystemPolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 273 NOTREACHED(); | |
| 274 return SBOX_ERROR_BAD_PARAMS; | |
| 275 } | |
| 276 break; | |
| 277 } | |
| 278 case SUBSYS_SYNC: { | |
| 279 if (!SyncPolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 280 NOTREACHED(); | |
| 281 return SBOX_ERROR_BAD_PARAMS; | |
| 282 } | |
| 283 break; | |
| 284 } | |
| 285 case SUBSYS_PROCESS: { | |
| 286 if (lockdown_level_ < USER_INTERACTIVE && | |
| 287 TargetPolicy::PROCESS_ALL_EXEC == semantics) { | |
| 288 // This is unsupported. This is a huge security risk to give full access | |
| 289 // to a process handle. | |
| 290 return SBOX_ERROR_UNSUPPORTED; | |
| 291 } | |
| 292 if (!ProcessPolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 293 NOTREACHED(); | |
| 294 return SBOX_ERROR_BAD_PARAMS; | |
| 295 } | |
| 296 break; | |
| 297 } | |
| 298 case SUBSYS_NAMED_PIPES: { | |
| 299 if (!NamedPipePolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 300 NOTREACHED(); | |
| 301 return SBOX_ERROR_BAD_PARAMS; | |
| 302 } | |
| 303 break; | |
| 304 } | |
| 305 case SUBSYS_REGISTRY: { | |
| 306 if (!RegistryPolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 307 NOTREACHED(); | |
| 308 return SBOX_ERROR_BAD_PARAMS; | |
| 309 } | |
| 310 break; | |
| 311 } | |
| 312 case SUBSYS_HANDLES: { | |
| 313 if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) { | |
| 314 NOTREACHED(); | |
| 315 return SBOX_ERROR_BAD_PARAMS; | |
| 316 } | |
| 317 break; | |
| 318 } | |
| 319 default: { | |
| 320 return SBOX_ERROR_UNSUPPORTED; | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 return SBOX_ALL_OK; | |
| 325 } | |
| 326 | |
| 327 ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) { | |
| 328 blacklisted_dlls_.push_back(std::wstring(dll_name)); | |
| 329 return SBOX_ALL_OK; | |
| 330 } | |
| 331 | |
| 332 ResultCode PolicyBase::AddKernelObjectToClose(const char16* handle_type, | |
| 333 const char16* handle_name) { | |
| 334 return handle_closer_.AddHandle(handle_type, handle_name); | |
| 335 } | |
| 336 | |
| 337 // When an IPC is ready in any of the targets we get called. We manage an array | |
| 338 // of IPC dispatchers which are keyed on the IPC tag so we normally delegate | |
| 339 // to the appropriate dispatcher unless we can handle the IPC call ourselves. | |
| 340 Dispatcher* PolicyBase::OnMessageReady(IPCParams* ipc, | |
| 341 CallbackGeneric* callback) { | |
| 342 DCHECK(callback); | |
| 343 static const IPCParams ping1 = {IPC_PING1_TAG, ULONG_TYPE}; | |
| 344 static const IPCParams ping2 = {IPC_PING2_TAG, INOUTPTR_TYPE}; | |
| 345 | |
| 346 if (ping1.Matches(ipc) || ping2.Matches(ipc)) { | |
| 347 *callback = reinterpret_cast<CallbackGeneric>( | |
| 348 static_cast<Callback1>(&PolicyBase::Ping)); | |
| 349 return this; | |
| 350 } | |
| 351 | |
| 352 Dispatcher* dispatch = GetDispatcher(ipc->ipc_tag); | |
| 353 if (!dispatch) { | |
| 354 NOTREACHED(); | |
| 355 return NULL; | |
| 356 } | |
| 357 return dispatch->OnMessageReady(ipc, callback); | |
| 358 } | |
| 359 | |
| 360 // Delegate to the appropriate dispatcher. | |
| 361 bool PolicyBase::SetupService(InterceptionManager* manager, int service) { | |
| 362 if (IPC_PING1_TAG == service || IPC_PING2_TAG == service) | |
| 363 return true; | |
| 364 | |
| 365 Dispatcher* dispatch = GetDispatcher(service); | |
| 366 if (!dispatch) { | |
| 367 NOTREACHED(); | |
| 368 return false; | |
| 369 } | |
| 370 return dispatch->SetupService(manager, service); | |
| 371 } | |
| 372 | |
| 373 DWORD PolicyBase::MakeJobObject(HANDLE* job) { | |
| 374 // Create the windows job object. | |
| 375 Job job_obj; | |
| 376 DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_); | |
| 377 if (ERROR_SUCCESS != result) { | |
| 378 return result; | |
| 379 } | |
| 380 *job = job_obj.Detach(); | |
| 381 return ERROR_SUCCESS; | |
| 382 } | |
| 383 | |
| 384 DWORD PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { | |
| 385 // Create the 'naked' token. This will be the permanent token associated | |
| 386 // with the process and therefore with any thread that is not impersonating. | |
| 387 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, | |
| 388 integrity_level_, PRIMARY); | |
| 389 if (ERROR_SUCCESS != result) { | |
| 390 return result; | |
| 391 } | |
| 392 // Create the 'better' token. We use this token as the one that the main | |
| 393 // thread uses when booting up the process. It should contain most of | |
| 394 // what we need (before reaching main( )) | |
| 395 result = CreateRestrictedToken(initial, initial_level_, | |
| 396 integrity_level_, IMPERSONATION); | |
| 397 if (ERROR_SUCCESS != result) { | |
| 398 ::CloseHandle(*lockdown); | |
| 399 return result; | |
| 400 } | |
| 401 return SBOX_ALL_OK; | |
| 402 } | |
| 403 | |
| 404 bool PolicyBase::AddTarget(TargetProcess* target) { | |
| 405 if (NULL != policy_) | |
| 406 policy_maker_->Done(); | |
| 407 | |
| 408 if (!SetupAllInterceptions(target)) | |
| 409 return false; | |
| 410 | |
| 411 if (!SetupHandleCloser(target)) | |
| 412 return false; | |
| 413 | |
| 414 // Initialize the sandbox infrastructure for the target. | |
| 415 if (ERROR_SUCCESS != target->Init(this, policy_, kIPCMemSize, kPolMemSize)) | |
| 416 return false; | |
| 417 | |
| 418 g_shared_delayed_integrity_level = delayed_integrity_level_; | |
| 419 ResultCode ret = target->TransferVariable( | |
| 420 "g_shared_delayed_integrity_level", | |
| 421 &g_shared_delayed_integrity_level, | |
| 422 sizeof(g_shared_delayed_integrity_level)); | |
| 423 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; | |
| 424 if (SBOX_ALL_OK != ret) | |
| 425 return false; | |
| 426 | |
| 427 AutoLock lock(&lock_); | |
| 428 targets_.push_back(target); | |
| 429 return true; | |
| 430 } | |
| 431 | |
| 432 bool PolicyBase::OnJobEmpty(HANDLE job) { | |
| 433 AutoLock lock(&lock_); | |
| 434 TargetSet::iterator it; | |
| 435 for (it = targets_.begin(); it != targets_.end(); ++it) { | |
| 436 if ((*it)->Job() == job) | |
| 437 break; | |
| 438 } | |
| 439 if (it == targets_.end()) { | |
| 440 return false; | |
| 441 } | |
| 442 TargetProcess* target = *it; | |
| 443 targets_.erase(it); | |
| 444 delete target; | |
| 445 return true; | |
| 446 } | |
| 447 | |
| 448 EvalResult PolicyBase::EvalPolicy(int service, | |
| 449 CountedParameterSetBase* params) { | |
| 450 if (NULL != policy_) { | |
| 451 if (NULL == policy_->entry[service]) { | |
| 452 // There is no policy for this particular service. This is not a big | |
| 453 // deal. | |
| 454 return DENY_ACCESS; | |
| 455 } | |
| 456 for (int i = 0; i < params->count; i++) { | |
| 457 if (!params->parameters[i].IsValid()) { | |
| 458 NOTREACHED(); | |
| 459 return SIGNAL_ALARM; | |
| 460 } | |
| 461 } | |
| 462 PolicyProcessor pol_evaluator(policy_->entry[service]); | |
| 463 PolicyResult result = pol_evaluator.Evaluate(kShortEval, | |
| 464 params->parameters, | |
| 465 params->count); | |
| 466 if (POLICY_MATCH == result) { | |
| 467 return pol_evaluator.GetAction(); | |
| 468 } | |
| 469 DCHECK(POLICY_ERROR != result); | |
| 470 } | |
| 471 | |
| 472 return DENY_ACCESS; | |
| 473 } | |
| 474 | |
| 475 // We service IPC_PING_TAG message which is a way to test a round trip of the | |
| 476 // IPC subsystem. We receive a integer cookie and we are expected to return the | |
| 477 // cookie times two (or three) and the current tick count. | |
| 478 bool PolicyBase::Ping(IPCInfo* ipc, void* arg1) { | |
| 479 switch (ipc->ipc_tag) { | |
| 480 case IPC_PING1_TAG: { | |
| 481 IPCInt ipc_int(arg1); | |
| 482 uint32 cookie = ipc_int.As32Bit(); | |
| 483 ipc->return_info.extended_count = 2; | |
| 484 ipc->return_info.extended[0].unsigned_int = ::GetTickCount(); | |
| 485 ipc->return_info.extended[1].unsigned_int = 2 * cookie; | |
| 486 return true; | |
| 487 } | |
| 488 case IPC_PING2_TAG: { | |
| 489 CountedBuffer* io_buffer = reinterpret_cast<CountedBuffer*>(arg1); | |
| 490 if (sizeof(uint32) != io_buffer->Size()) | |
| 491 return false; | |
| 492 | |
| 493 uint32* cookie = reinterpret_cast<uint32*>(io_buffer->Buffer()); | |
| 494 *cookie = (*cookie) * 3; | |
| 495 return true; | |
| 496 } | |
| 497 default: return false; | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 Dispatcher* PolicyBase::GetDispatcher(int ipc_tag) { | |
| 502 if (ipc_tag >= IPC_LAST_TAG || ipc_tag <= IPC_UNUSED_TAG) | |
| 503 return NULL; | |
| 504 | |
| 505 return ipc_targets_[ipc_tag]; | |
| 506 } | |
| 507 | |
| 508 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { | |
| 509 InterceptionManager manager(target, relaxed_interceptions_); | |
| 510 | |
| 511 if (policy_) { | |
| 512 for (int i = 0; i < IPC_LAST_TAG; i++) { | |
| 513 if (policy_->entry[i] && !ipc_targets_[i]->SetupService(&manager, i)) | |
| 514 return false; | |
| 515 } | |
| 516 } | |
| 517 | |
| 518 if (!blacklisted_dlls_.empty()) { | |
| 519 std::vector<std::wstring>::iterator it = blacklisted_dlls_.begin(); | |
| 520 for (; it != blacklisted_dlls_.end(); ++it) { | |
| 521 manager.AddToUnloadModules(it->c_str()); | |
| 522 } | |
| 523 } | |
| 524 | |
| 525 if (!handle_closer_.SetupHandleInterceptions(&manager)) | |
| 526 return false; | |
| 527 | |
| 528 if (!SetupBasicInterceptions(&manager)) | |
| 529 return false; | |
| 530 | |
| 531 if (!manager.InitializeInterceptions()) | |
| 532 return false; | |
| 533 | |
| 534 // Finally, setup imports on the target so the interceptions can work. | |
| 535 return SetupNtdllImports(target); | |
| 536 } | |
| 537 | |
| 538 bool PolicyBase::SetupHandleCloser(TargetProcess* target) { | |
| 539 return handle_closer_.InitializeTargetHandles(target); | |
| 540 } | |
| 541 | |
| 542 } // namespace sandbox | |
| OLD | NEW |