Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: content/common/sandbox_win.cc

Issue 1923653002: Wire up process launch error codes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix android Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/sandbox_win.h" 5 #include "content/common/sandbox_win.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 10
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); 274 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError();
275 return true; 275 return true;
276 } 276 }
277 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) 277 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK)
278 return true; 278 return true;
279 279
280 return false; 280 return false;
281 } 281 }
282 282
283 // Adds the generic policy rules to a sandbox TargetPolicy. 283 // Adds the generic policy rules to a sandbox TargetPolicy.
284 bool AddGenericPolicy(sandbox::TargetPolicy* policy) { 284 sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) {
285 sandbox::ResultCode result; 285 sandbox::ResultCode result;
286 286
287 // Add the policy for the client side of a pipe. It is just a file 287 // Add the policy for the client side of a pipe. It is just a file
288 // in the \pipe\ namespace. We restrict it to pipes that start with 288 // in the \pipe\ namespace. We restrict it to pipes that start with
289 // "chrome." so the sandboxed process cannot connect to system services. 289 // "chrome." so the sandboxed process cannot connect to system services.
290 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, 290 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
291 sandbox::TargetPolicy::FILES_ALLOW_ANY, 291 sandbox::TargetPolicy::FILES_ALLOW_ANY,
292 L"\\??\\pipe\\chrome.*"); 292 L"\\??\\pipe\\chrome.*");
293 if (result != sandbox::SBOX_ALL_OK) 293 if (result != sandbox::SBOX_ALL_OK)
294 return false; 294 return result;
295 295
296 // Add the policy for the server side of nacl pipe. It is just a file 296 // Add the policy for the server side of nacl pipe. It is just a file
297 // in the \pipe\ namespace. We restrict it to pipes that start with 297 // in the \pipe\ namespace. We restrict it to pipes that start with
298 // "chrome.nacl" so the sandboxed process cannot connect to 298 // "chrome.nacl" so the sandboxed process cannot connect to
299 // system services. 299 // system services.
300 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, 300 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
301 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, 301 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
302 L"\\\\.\\pipe\\chrome.nacl.*"); 302 L"\\\\.\\pipe\\chrome.nacl.*");
303 if (result != sandbox::SBOX_ALL_OK) 303 if (result != sandbox::SBOX_ALL_OK)
304 return false; 304 return result;
305 305
306 // Allow the server side of sync sockets, which are pipes that have 306 // Allow the server side of sync sockets, which are pipes that have
307 // the "chrome.sync" namespace and a randomly generated suffix. 307 // the "chrome.sync" namespace and a randomly generated suffix.
308 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, 308 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
309 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, 309 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
310 L"\\\\.\\pipe\\chrome.sync.*"); 310 L"\\\\.\\pipe\\chrome.sync.*");
311 if (result != sandbox::SBOX_ALL_OK) 311 if (result != sandbox::SBOX_ALL_OK)
312 return false; 312 return result;
313 313
314 // Add the policy for debug message only in debug 314 // Add the policy for debug message only in debug
315 #ifndef NDEBUG 315 #ifndef NDEBUG
316 base::FilePath app_dir; 316 base::FilePath app_dir;
317 if (!PathService::Get(base::DIR_MODULE, &app_dir)) 317 if (!PathService::Get(base::DIR_MODULE, &app_dir))
318 return false; 318 return false;
319 319
320 wchar_t long_path_buf[MAX_PATH]; 320 wchar_t long_path_buf[MAX_PATH];
321 DWORD long_path_return_value = GetLongPathName(app_dir.value().c_str(), 321 DWORD long_path_return_value = GetLongPathName(app_dir.value().c_str(),
322 long_path_buf, 322 long_path_buf,
323 MAX_PATH); 323 MAX_PATH);
324 if (long_path_return_value == 0 || long_path_return_value >= MAX_PATH) 324 if (long_path_return_value == 0 || long_path_return_value >= MAX_PATH)
325 return false; 325 return false;
326 326
327 base::FilePath debug_message(long_path_buf); 327 base::FilePath debug_message(long_path_buf);
328 debug_message = debug_message.AppendASCII("debug_message.exe"); 328 debug_message = debug_message.AppendASCII("debug_message.exe");
329 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS, 329 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS,
330 sandbox::TargetPolicy::PROCESS_MIN_EXEC, 330 sandbox::TargetPolicy::PROCESS_MIN_EXEC,
331 debug_message.value().c_str()); 331 debug_message.value().c_str());
332 if (result != sandbox::SBOX_ALL_OK) 332 if (result != sandbox::SBOX_ALL_OK)
333 return false; 333 return result;
334 #endif // NDEBUG 334 #endif // NDEBUG
335 335
336 // Add the policy for read-only PDB file access for stack traces. 336 // Add the policy for read-only PDB file access for stack traces.
337 #if !defined(OFFICIAL_BUILD) 337 #if !defined(OFFICIAL_BUILD)
338 base::FilePath exe; 338 base::FilePath exe;
339 if (!PathService::Get(base::FILE_EXE, &exe)) 339 if (!PathService::Get(base::FILE_EXE, &exe))
340 return false; 340 return sandbox::SBOX_ERROR_GENERIC;
341 base::FilePath pdb_path = exe.DirName().Append(L"*.pdb"); 341 base::FilePath pdb_path = exe.DirName().Append(L"*.pdb");
342 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, 342 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
343 sandbox::TargetPolicy::FILES_ALLOW_READONLY, 343 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
344 pdb_path.value().c_str()); 344 pdb_path.value().c_str());
345 if (result != sandbox::SBOX_ALL_OK) 345 if (result != sandbox::SBOX_ALL_OK)
346 return false; 346 return result;
347 #endif 347 #endif
348 348
349 #if defined(SANITIZER_COVERAGE) 349 #if defined(SANITIZER_COVERAGE)
350 DWORD coverage_dir_size = 350 DWORD coverage_dir_size =
351 ::GetEnvironmentVariable(L"SANITIZER_COVERAGE_DIR", NULL, 0); 351 ::GetEnvironmentVariable(L"SANITIZER_COVERAGE_DIR", NULL, 0);
352 if (coverage_dir_size == 0) { 352 if (coverage_dir_size == 0) {
353 LOG(WARNING) << "SANITIZER_COVERAGE_DIR was not set, coverage won't work."; 353 LOG(WARNING) << "SANITIZER_COVERAGE_DIR was not set, coverage won't work.";
354 } else { 354 } else {
355 std::wstring coverage_dir; 355 std::wstring coverage_dir;
356 wchar_t* coverage_dir_str = 356 wchar_t* coverage_dir_str =
357 base::WriteInto(&coverage_dir, coverage_dir_size); 357 base::WriteInto(&coverage_dir, coverage_dir_size);
358 coverage_dir_size = ::GetEnvironmentVariable( 358 coverage_dir_size = ::GetEnvironmentVariable(
359 L"SANITIZER_COVERAGE_DIR", coverage_dir_str, coverage_dir_size); 359 L"SANITIZER_COVERAGE_DIR", coverage_dir_str, coverage_dir_size);
360 CHECK(coverage_dir.size() == coverage_dir_size); 360 CHECK(coverage_dir.size() == coverage_dir_size);
361 base::FilePath sancov_path = 361 base::FilePath sancov_path =
362 base::FilePath(coverage_dir).Append(L"*.sancov"); 362 base::FilePath(coverage_dir).Append(L"*.sancov");
363 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, 363 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
364 sandbox::TargetPolicy::FILES_ALLOW_ANY, 364 sandbox::TargetPolicy::FILES_ALLOW_ANY,
365 sancov_path.value().c_str()); 365 sancov_path.value().c_str());
366 if (result != sandbox::SBOX_ALL_OK) 366 if (result != sandbox::SBOX_ALL_OK)
367 return false; 367 return result;
368 } 368 }
369 #endif 369 #endif
370 370
371 AddGenericDllEvictionPolicy(policy); 371 AddGenericDllEvictionPolicy(policy);
372 return true; 372 return sandbox::SBOX_ALL_OK;
373 } 373 }
374 374
375 bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) { 375 sandbox::ResultCode AddPolicyForSandboxedProcess(
376 sandbox::TargetPolicy* policy) {
376 sandbox::ResultCode result = sandbox::SBOX_ALL_OK; 377 sandbox::ResultCode result = sandbox::SBOX_ALL_OK;
377 378
378 // Win8+ adds a device DeviceApi that we don't need. 379 // Win8+ adds a device DeviceApi that we don't need.
379 if (base::win::GetVersion() > base::win::VERSION_WIN7) 380 if (base::win::GetVersion() > base::win::VERSION_WIN7)
380 result = policy->AddKernelObjectToClose(L"File", L"\\Device\\DeviceApi"); 381 result = policy->AddKernelObjectToClose(L"File", L"\\Device\\DeviceApi");
381 if (result != sandbox::SBOX_ALL_OK) 382 if (result != sandbox::SBOX_ALL_OK)
382 return false; 383 return result;
383 384
384 // Close the proxy settings on XP. 385 // Close the proxy settings on XP.
385 if (base::win::GetVersion() <= base::win::VERSION_SERVER_2003) 386 if (base::win::GetVersion() <= base::win::VERSION_SERVER_2003)
386 result = policy->AddKernelObjectToClose(L"Key", 387 result = policy->AddKernelObjectToClose(L"Key",
387 L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\" \ 388 L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\" \
388 L"CurrentVersion\\Internet Settings"); 389 L"CurrentVersion\\Internet Settings");
389 if (result != sandbox::SBOX_ALL_OK) 390 if (result != sandbox::SBOX_ALL_OK)
390 return false; 391 return result;
391 392
392 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; 393 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
393 if (base::win::GetVersion() > base::win::VERSION_XP) { 394 if (base::win::GetVersion() > base::win::VERSION_XP) {
394 // On 2003/Vista the initial token has to be restricted if the main 395 // On 2003/Vista the initial token has to be restricted if the main
395 // token is restricted. 396 // token is restricted.
396 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; 397 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
397 } 398 }
398 399
399 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); 400 result = policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN);
401 if (result != sandbox::SBOX_ALL_OK)
402 return result;
400 // Prevents the renderers from manipulating low-integrity processes. 403 // Prevents the renderers from manipulating low-integrity processes.
401 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED); 404 result = policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED);
402 policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); 405 if (result != sandbox::SBOX_ALL_OK)
406 return result;
407 result = policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
408 if (result != sandbox::SBOX_ALL_OK)
409 return result;
403 policy->SetLockdownDefaultDacl(); 410 policy->SetLockdownDefaultDacl();
404 411
405 if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(true)) { 412 result = policy->SetAlternateDesktop(true);
413 if (result != sandbox::SBOX_ALL_OK) {
406 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; 414 DLOG(WARNING) << "Failed to apply desktop security to the renderer";
415 return result;
407 } 416 }
408 417
409 return true; 418 return result;
410 } 419 }
411 420
412 // Updates the command line arguments with debug-related flags. If debug flags 421 // Updates the command line arguments with debug-related flags. If debug flags
413 // have been used with this process, they will be filtered and added to 422 // have been used with this process, they will be filtered and added to
414 // command_line as needed. 423 // command_line as needed.
415 void ProcessDebugFlags(base::CommandLine* command_line) { 424 void ProcessDebugFlags(base::CommandLine* command_line) {
416 const base::CommandLine& current_cmd_line = 425 const base::CommandLine& current_cmd_line =
417 *base::CommandLine::ForCurrentProcess(); 426 *base::CommandLine::ForCurrentProcess();
418 std::string type = command_line->GetSwitchValueASCII(switches::kProcessType); 427 std::string type = command_line->GetSwitchValueASCII(switches::kProcessType);
419 if (current_cmd_line.HasSwitch(switches::kWaitForDebuggerChildren)) { 428 if (current_cmd_line.HasSwitch(switches::kWaitForDebuggerChildren)) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 if (command_line.HasSwitch(switches::kDisableAppContainer)) 550 if (command_line.HasSwitch(switches::kDisableAppContainer))
542 return false; 551 return false;
543 if (command_line.HasSwitch(switches::kEnableAppContainer)) 552 if (command_line.HasSwitch(switches::kEnableAppContainer))
544 return true; 553 return true;
545 return base::StartsWith(appcontainer_group_name, "Enabled", 554 return base::StartsWith(appcontainer_group_name, "Enabled",
546 base::CompareCase::INSENSITIVE_ASCII); 555 base::CompareCase::INSENSITIVE_ASCII);
547 } 556 }
548 557
549 } // namespace 558 } // namespace
550 559
551 void SetJobLevel(const base::CommandLine& cmd_line, 560 sandbox::ResultCode SetJobLevel(const base::CommandLine& cmd_line,
552 sandbox::JobLevel job_level, 561 sandbox::JobLevel job_level,
553 uint32_t ui_exceptions, 562 uint32_t ui_exceptions,
554 sandbox::TargetPolicy* policy) { 563 sandbox::TargetPolicy* policy) {
555 if (ShouldSetJobLevel(cmd_line)) { 564 if (!ShouldSetJobLevel(cmd_line))
565 return policy->SetJobLevel(sandbox::JOB_NONE, 0);
566
556 #ifdef _WIN64 567 #ifdef _WIN64
557 policy->SetJobMemoryLimit(4ULL * 1024 * 1024 * 1024); 568 sandbox::ResultCode ret =
569 policy->SetJobMemoryLimit(4ULL * 1024 * 1024 * 1024);
570 if (ret != sandbox::SBOX_ALL_OK)
571 return ret;
558 #endif 572 #endif
559 policy->SetJobLevel(job_level, ui_exceptions); 573 return policy->SetJobLevel(job_level, ui_exceptions);
560 } else {
561 policy->SetJobLevel(sandbox::JOB_NONE, 0);
562 }
563 } 574 }
564 575
565 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. 576 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper.
566 // Just have to figure out what needs to be warmed up first. 577 // Just have to figure out what needs to be warmed up first.
567 void AddBaseHandleClosePolicy(sandbox::TargetPolicy* policy) { 578 sandbox::ResultCode AddBaseHandleClosePolicy(sandbox::TargetPolicy* policy) {
568 // TODO(cpu): Add back the BaseNamedObjects policy. 579 // TODO(cpu): Add back the BaseNamedObjects policy.
569 base::string16 object_path = PrependWindowsSessionPath( 580 base::string16 object_path = PrependWindowsSessionPath(
570 L"\\BaseNamedObjects\\windows_shell_global_counters"); 581 L"\\BaseNamedObjects\\windows_shell_global_counters");
571 policy->AddKernelObjectToClose(L"Section", object_path.data()); 582 return policy->AddKernelObjectToClose(L"Section", object_path.data());
572 } 583 }
573 584
574 void AddAppContainerPolicy(sandbox::TargetPolicy* policy, const wchar_t* sid) { 585 sandbox::ResultCode AddAppContainerPolicy(sandbox::TargetPolicy* policy,
586 const wchar_t* sid) {
575 if (IsAppContainerEnabled()) 587 if (IsAppContainerEnabled())
576 policy->SetLowBox(sid); 588 return policy->SetLowBox(sid);
589 return sandbox::SBOX_ALL_OK;
577 } 590 }
578 591
579 bool AddWin32kLockdownPolicy(sandbox::TargetPolicy* policy, bool enable_opm) { 592 sandbox::ResultCode AddWin32kLockdownPolicy(sandbox::TargetPolicy* policy,
593 bool enable_opm) {
580 #if !defined(NACL_WIN64) 594 #if !defined(NACL_WIN64)
581 if (!IsWin32kRendererLockdownEnabled()) 595 if (!IsWin32kRendererLockdownEnabled())
582 return true; 596 return sandbox::SBOX_ALL_OK;
583 597
584 // Enable win32k lockdown if not already. 598 // Enable win32k lockdown if not already.
585 sandbox::MitigationFlags flags = policy->GetProcessMitigations(); 599 sandbox::MitigationFlags flags = policy->GetProcessMitigations();
586 if ((flags & sandbox::MITIGATION_WIN32K_DISABLE) == 600 if ((flags & sandbox::MITIGATION_WIN32K_DISABLE) ==
587 sandbox::MITIGATION_WIN32K_DISABLE) 601 sandbox::MITIGATION_WIN32K_DISABLE)
588 return true; 602 return sandbox::SBOX_ALL_OK;
589 603
590 sandbox::ResultCode result = 604 sandbox::ResultCode result =
591 policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN, 605 policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
592 enable_opm ? sandbox::TargetPolicy::IMPLEMENT_OPM_APIS 606 enable_opm ? sandbox::TargetPolicy::IMPLEMENT_OPM_APIS
593 : sandbox::TargetPolicy::FAKE_USER_GDI_INIT, 607 : sandbox::TargetPolicy::FAKE_USER_GDI_INIT,
594 nullptr); 608 nullptr);
595 if (result != sandbox::SBOX_ALL_OK) 609 if (result != sandbox::SBOX_ALL_OK)
596 return false; 610 return result;
597 if (enable_opm) 611 if (enable_opm)
598 policy->SetEnableOPMRedirection(); 612 policy->SetEnableOPMRedirection();
613
599 flags |= sandbox::MITIGATION_WIN32K_DISABLE; 614 flags |= sandbox::MITIGATION_WIN32K_DISABLE;
600 result = policy->SetProcessMitigations(flags); 615 return policy->SetProcessMitigations(flags);
601 if (result != sandbox::SBOX_ALL_OK) 616 #else
602 return false; 617 return sandbox::SBOX_ALL_OK;
603 #endif 618 #endif
604 return true;
605 } 619 }
606 620
607 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { 621 bool InitBrokerServices(sandbox::BrokerServices* broker_services) {
608 // TODO(abarth): DCHECK(CalledOnValidThread()); 622 // TODO(abarth): DCHECK(CalledOnValidThread());
609 // See <http://b/1287166>. 623 // See <http://b/1287166>.
610 DCHECK(broker_services); 624 DCHECK(broker_services);
611 DCHECK(!g_broker_services); 625 DCHECK(!g_broker_services);
612 sandbox::ResultCode result = broker_services->Init(); 626 sandbox::ResultCode result = broker_services->Init();
613 g_broker_services = broker_services; 627 g_broker_services = broker_services;
614 628
(...skipping 29 matching lines...) Expand all
644 } 658 }
645 659
646 bool InitTargetServices(sandbox::TargetServices* target_services) { 660 bool InitTargetServices(sandbox::TargetServices* target_services) {
647 DCHECK(target_services); 661 DCHECK(target_services);
648 DCHECK(!g_target_services); 662 DCHECK(!g_target_services);
649 sandbox::ResultCode result = target_services->Init(); 663 sandbox::ResultCode result = target_services->Init();
650 g_target_services = target_services; 664 g_target_services = target_services;
651 return sandbox::SBOX_ALL_OK == result; 665 return sandbox::SBOX_ALL_OK == result;
652 } 666 }
653 667
654 base::Process StartSandboxedProcess( 668 sandbox::ResultCode StartSandboxedProcess(
655 SandboxedProcessLauncherDelegate* delegate, 669 SandboxedProcessLauncherDelegate* delegate,
656 base::CommandLine* cmd_line, 670 base::CommandLine* cmd_line,
657 const base::HandlesToInheritVector& handles_to_inherit) { 671 const base::HandlesToInheritVector& handles_to_inherit,
672 base::Process* process) {
658 DCHECK(delegate); 673 DCHECK(delegate);
659 const base::CommandLine& browser_command_line = 674 const base::CommandLine& browser_command_line =
660 *base::CommandLine::ForCurrentProcess(); 675 *base::CommandLine::ForCurrentProcess();
661 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); 676 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType);
662 677
663 TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str); 678 TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str);
664 679
665 // Propagate the --allow-no-job flag if present. 680 // Propagate the --allow-no-job flag if present.
666 if (browser_command_line.HasSwitch(switches::kAllowNoSandboxJob) && 681 if (browser_command_line.HasSwitch(switches::kAllowNoSandboxJob) &&
667 !cmd_line->HasSwitch(switches::kAllowNoSandboxJob)) { 682 !cmd_line->HasSwitch(switches::kAllowNoSandboxJob)) {
668 cmd_line->AppendSwitch(switches::kAllowNoSandboxJob); 683 cmd_line->AppendSwitch(switches::kAllowNoSandboxJob);
669 } 684 }
670 685
671 ProcessDebugFlags(cmd_line); 686 ProcessDebugFlags(cmd_line);
672 687
673 if ((!delegate->ShouldSandbox()) || 688 if ((!delegate->ShouldSandbox()) ||
674 browser_command_line.HasSwitch(switches::kNoSandbox) || 689 browser_command_line.HasSwitch(switches::kNoSandbox) ||
675 cmd_line->HasSwitch(switches::kNoSandbox)) { 690 cmd_line->HasSwitch(switches::kNoSandbox)) {
676 base::LaunchOptions options; 691 base::LaunchOptions options;
677 692
678 base::HandlesToInheritVector handles = handles_to_inherit; 693 base::HandlesToInheritVector handles = handles_to_inherit;
679 if (!handles_to_inherit.empty()) { 694 if (!handles_to_inherit.empty()) {
680 options.inherit_handles = true; 695 options.inherit_handles = true;
681 options.handles_to_inherit = &handles; 696 options.handles_to_inherit = &handles;
682 } 697 }
683 base::Process process = base::LaunchProcess(*cmd_line, options); 698 base::Process unsandboxed_process = base::LaunchProcess(*cmd_line, options);
684 699
685 // TODO(rvargas) crbug.com/417532: Don't share a raw handle. 700 // TODO(rvargas) crbug.com/417532: Don't share a raw handle.
686 g_broker_services->AddTargetPeer(process.Handle()); 701 g_broker_services->AddTargetPeer(unsandboxed_process.Handle());
687 return process; 702
703 *process = std::move(unsandboxed_process);
704 return sandbox::SBOX_ALL_OK;
688 } 705 }
689 706
690 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); 707 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy();
691 708
692 // Add any handles to be inherited to the policy. 709 // Add any handles to be inherited to the policy.
693 for (HANDLE handle : handles_to_inherit) 710 for (HANDLE handle : handles_to_inherit)
694 policy->AddHandleToShare(handle); 711 policy->AddHandleToShare(handle);
695 712
696 // Pre-startup mitigations. 713 // Pre-startup mitigations.
697 sandbox::MitigationFlags mitigations = 714 sandbox::MitigationFlags mitigations =
698 sandbox::MITIGATION_HEAP_TERMINATE | 715 sandbox::MITIGATION_HEAP_TERMINATE |
699 sandbox::MITIGATION_BOTTOM_UP_ASLR | 716 sandbox::MITIGATION_BOTTOM_UP_ASLR |
700 sandbox::MITIGATION_DEP | 717 sandbox::MITIGATION_DEP |
701 sandbox::MITIGATION_DEP_NO_ATL_THUNK | 718 sandbox::MITIGATION_DEP_NO_ATL_THUNK |
702 sandbox::MITIGATION_SEHOP | 719 sandbox::MITIGATION_SEHOP |
703 sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE | 720 sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE |
704 sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE | 721 sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE |
705 sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL; 722 sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL;
706 #if !defined(NACL_WIN64) 723 #if !defined(NACL_WIN64)
707 // Don't block font loading with GDI. 724 // Don't block font loading with GDI.
708 if (!gfx::win::ShouldUseDirectWrite()) 725 if (!gfx::win::ShouldUseDirectWrite())
709 mitigations ^= sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE; 726 mitigations ^= sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE;
710 #endif 727 #endif
711 728
712 if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) 729 sandbox::ResultCode result = sandbox::SBOX_ERROR_GENERIC;
713 return base::Process(); 730
731 result = policy->SetProcessMitigations(mitigations);
732
733 if (result != sandbox::SBOX_ALL_OK)
734 return result;
714 735
715 #if !defined(NACL_WIN64) 736 #if !defined(NACL_WIN64)
716 if (type_str == switches::kRendererProcess && 737 if (type_str == switches::kRendererProcess &&
717 IsWin32kRendererLockdownEnabled()) { 738 IsWin32kRendererLockdownEnabled()) {
718 if (!AddWin32kLockdownPolicy(policy, false)) 739 result = AddWin32kLockdownPolicy(policy, false);
719 return base::Process(); 740 if (result != sandbox::SBOX_ALL_OK)
741 return result;
720 } 742 }
721 #endif 743 #endif
722 744
723 // Post-startup mitigations. 745 // Post-startup mitigations.
724 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS | 746 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
725 sandbox::MITIGATION_DLL_SEARCH_ORDER; 747 sandbox::MITIGATION_DLL_SEARCH_ORDER;
726 748
727 if (policy->SetDelayedProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) 749 result = policy->SetDelayedProcessMitigations(mitigations);
728 return base::Process(); 750 if (result != sandbox::SBOX_ALL_OK)
751 return result;
729 752
730 SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy); 753 result = SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy);
754 if (result != sandbox::SBOX_ALL_OK)
755 return result;
731 756
732 if (!delegate->DisableDefaultPolicy()) { 757 if (!delegate->DisableDefaultPolicy()) {
733 if (!AddPolicyForSandboxedProcess(policy)) 758 result = AddPolicyForSandboxedProcess(policy);
734 return base::Process(); 759 if (result != sandbox::SBOX_ALL_OK)
760 return result;
735 } 761 }
736 762
737 #if !defined(NACL_WIN64) 763 #if !defined(NACL_WIN64)
738 // NOTE: This is placed at function scope so that it stays alive through 764 // NOTE: This is placed at function scope so that it stays alive through
739 // process launch. 765 // process launch.
740 base::SharedMemory direct_write_font_cache_section; 766 base::SharedMemory direct_write_font_cache_section;
741 if (type_str == switches::kRendererProcess || 767 if (type_str == switches::kRendererProcess ||
742 type_str == switches::kPpapiPluginProcess) { 768 type_str == switches::kPpapiPluginProcess) {
743 if (gfx::win::ShouldUseDirectWrite()) { 769 if (gfx::win::ShouldUseDirectWrite()) {
744 AddDirectory(base::DIR_WINDOWS_FONTS, 770 AddDirectory(base::DIR_WINDOWS_FONTS,
745 NULL, 771 NULL,
746 true, 772 true,
747 sandbox::TargetPolicy::FILES_ALLOW_READONLY, 773 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
748 policy); 774 policy);
749 } 775 }
750 } 776 }
751 #endif 777 #endif
752 778
753 if (type_str != switches::kRendererProcess) { 779 if (type_str != switches::kRendererProcess) {
754 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into 780 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into
755 // this subprocess. See 781 // this subprocess. See
756 // http://code.google.com/p/chromium/issues/detail?id=25580 782 // http://code.google.com/p/chromium/issues/detail?id=25580
757 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); 783 cmd_line->AppendSwitchASCII("ignored", " --type=renderer ");
758 } 784 }
759 785
760 if (!AddGenericPolicy(policy)) { 786 result = AddGenericPolicy(policy);
787
788 if (result != sandbox::SBOX_ALL_OK) {
761 NOTREACHED(); 789 NOTREACHED();
762 return base::Process(); 790 return result;
763 } 791 }
764 792
765 // Allow the renderer and gpu processes to access the log file. 793 // Allow the renderer and gpu processes to access the log file.
766 if (type_str == switches::kRendererProcess || 794 if (type_str == switches::kRendererProcess ||
767 type_str == switches::kGpuProcess) { 795 type_str == switches::kGpuProcess) {
768 if (logging::IsLoggingToFileEnabled()) { 796 if (logging::IsLoggingToFileEnabled()) {
769 DCHECK(base::FilePath(logging::GetLogFileFullPath()).IsAbsolute()); 797 DCHECK(base::FilePath(logging::GetLogFileFullPath()).IsAbsolute());
770 policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, 798 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
771 sandbox::TargetPolicy::FILES_ALLOW_ANY, 799 sandbox::TargetPolicy::FILES_ALLOW_ANY,
772 logging::GetLogFileFullPath().c_str()); 800 logging::GetLogFileFullPath().c_str());
801 if (result != sandbox::SBOX_ALL_OK)
802 return result;
773 } 803 }
774 } 804 }
775 805
776 #if !defined(OFFICIAL_BUILD) 806 #if !defined(OFFICIAL_BUILD)
777 // If stdout/stderr point to a Windows console, these calls will 807 // If stdout/stderr point to a Windows console, these calls will
778 // have no effect. 808 // have no effect. These calls can fail with SBOX_ERROR_BAD_PARAMS.
779 policy->SetStdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)); 809 policy->SetStdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE));
780 policy->SetStderrHandle(GetStdHandle(STD_ERROR_HANDLE)); 810 policy->SetStderrHandle(GetStdHandle(STD_ERROR_HANDLE));
781 #endif 811 #endif
782 812
783 if (!delegate->PreSpawnTarget(policy)) 813 if (!delegate->PreSpawnTarget(policy))
784 return base::Process(); 814 return sandbox::SBOX_ERROR_DELEGATE_PRE_SPAWN;
785 815
786 TRACE_EVENT_BEGIN0("startup", "StartProcessWithAccess::LAUNCHPROCESS"); 816 TRACE_EVENT_BEGIN0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
787 817
788 PROCESS_INFORMATION temp_process_info = {}; 818 PROCESS_INFORMATION temp_process_info = {};
789 sandbox::ResultCode result = g_broker_services->SpawnTarget( 819 result = g_broker_services->SpawnTarget(
790 cmd_line->GetProgram().value().c_str(), 820 cmd_line->GetProgram().value().c_str(),
791 cmd_line->GetCommandLineString().c_str(), policy, &temp_process_info); 821 cmd_line->GetCommandLineString().c_str(), policy, &temp_process_info);
792 DWORD last_error = ::GetLastError(); 822 DWORD last_error = ::GetLastError();
793 base::win::ScopedProcessInformation target(temp_process_info); 823 base::win::ScopedProcessInformation target(temp_process_info);
794 824
795 TRACE_EVENT_END0("startup", "StartProcessWithAccess::LAUNCHPROCESS"); 825 TRACE_EVENT_END0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
796 826
797 if (sandbox::SBOX_ALL_OK != result) { 827 if (sandbox::SBOX_ALL_OK != result) {
798 if (result == sandbox::SBOX_ERROR_GENERIC) 828 if (result == sandbox::SBOX_ERROR_GENERIC)
799 DPLOG(ERROR) << "Failed to launch process"; 829 DPLOG(ERROR) << "Failed to launch process";
800 else if (result == sandbox::SBOX_ERROR_CREATE_PROCESS) { 830 else if (result == sandbox::SBOX_ERROR_CREATE_PROCESS) {
801 // TODO(shrikant): Remove this special case handling after determining 831 // TODO(shrikant): Remove this special case handling after determining
802 // cause for lowbox/createprocess errors. 832 // cause for lowbox/createprocess errors.
803 sandbox::PolicyBase* policy_base = 833 sandbox::PolicyBase* policy_base =
804 static_cast<sandbox::PolicyBase*>(policy); 834 static_cast<sandbox::PolicyBase*>(policy);
805 UMA_HISTOGRAM_SPARSE_SLOWLY(policy_base->GetLowBoxSid() ? 835 UMA_HISTOGRAM_SPARSE_SLOWLY(policy_base->GetLowBoxSid() ?
806 "Process.Sandbox.Lowbox.Launch.Error" : 836 "Process.Sandbox.Lowbox.Launch.Error" :
807 "Process.Sandbox.Launch.Error", 837 "Process.Sandbox.Launch.Error",
808 last_error); 838 last_error);
809 } else 839 } else
810 DLOG(ERROR) << "Failed to launch process. Error: " << result; 840 DLOG(ERROR) << "Failed to launch process. Error: " << result;
811 841
812 return base::Process(); 842 return result;
813 } 843 }
814 844
815 delegate->PostSpawnTarget(target.process_handle()); 845 delegate->PostSpawnTarget(target.process_handle());
816 846
817 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1)); 847 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1));
818 return base::Process(target.TakeProcessHandle()); 848 *process = base::Process(target.TakeProcessHandle());
849 return sandbox::SBOX_ALL_OK;
819 } 850 }
820 851
821 bool BrokerAddTargetPeer(HANDLE peer_process) { 852 bool BrokerAddTargetPeer(HANDLE peer_process) {
822 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; 853 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK;
823 } 854 }
824 855
825 } // namespace content 856 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698