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

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

Issue 649533003: C++11 declares a type safe null pointer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed Presubmit errors Created 6 years, 2 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
« no previous file with comments | « content/common/sandbox_mac_unittest_helper.h ('k') | content/common/savable_url_schemes.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <string> 7 #include <string>
8 8
9 #include "base/base_switches.h" 9 #include "base/base_switches.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 13 matching lines...) Expand all
24 #include "content/public/common/content_client.h" 24 #include "content/public/common/content_client.h"
25 #include "content/public/common/content_switches.h" 25 #include "content/public/common/content_switches.h"
26 #include "content/public/common/sandbox_init.h" 26 #include "content/public/common/sandbox_init.h"
27 #include "content/public/common/sandboxed_process_launcher_delegate.h" 27 #include "content/public/common/sandboxed_process_launcher_delegate.h"
28 #include "sandbox/win/src/process_mitigations.h" 28 #include "sandbox/win/src/process_mitigations.h"
29 #include "sandbox/win/src/sandbox.h" 29 #include "sandbox/win/src/sandbox.h"
30 #include "sandbox/win/src/sandbox_nt_util.h" 30 #include "sandbox/win/src/sandbox_nt_util.h"
31 #include "sandbox/win/src/win_utils.h" 31 #include "sandbox/win/src/win_utils.h"
32 #include "ui/gfx/win/dpi.h" 32 #include "ui/gfx/win/dpi.h"
33 33
34 static sandbox::BrokerServices* g_broker_services = NULL; 34 static sandbox::BrokerServices* g_broker_services = nullptr;
35 static sandbox::TargetServices* g_target_services = NULL; 35 static sandbox::TargetServices* g_target_services = nullptr;
36 36
37 namespace content { 37 namespace content {
38 namespace { 38 namespace {
39 39
40 // The DLLs listed here are known (or under strong suspicion) of causing crashes 40 // The DLLs listed here are known (or under strong suspicion) of causing crashes
41 // when they are loaded in the renderer. Note: at runtime we generate short 41 // when they are loaded in the renderer. Note: at runtime we generate short
42 // versions of the dll name only if the dll has an extension. 42 // versions of the dll name only if the dll has an extension.
43 // For more information about how this list is generated, and how to get off 43 // For more information about how this list is generated, and how to get off
44 // of it, see: 44 // of it, see:
45 // https://sites.google.com/a/chromium.org/dev/Home/third-party-developers 45 // https://sites.google.com/a/chromium.org/dev/Home/third-party-developers
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 base::FilePath fname(path); 176 base::FilePath fname(path);
177 return (fname.BaseName().value() == module_name); 177 return (fname.BaseName().value() == module_name);
178 } 178 }
179 179
180 // Adds a single dll by |module_name| into the |policy| blacklist. 180 // Adds a single dll by |module_name| into the |policy| blacklist.
181 // If |check_in_browser| is true we only add an unload policy only if the dll 181 // If |check_in_browser| is true we only add an unload policy only if the dll
182 // is also loaded in this process. 182 // is also loaded in this process.
183 void BlacklistAddOneDll(const wchar_t* module_name, 183 void BlacklistAddOneDll(const wchar_t* module_name,
184 bool check_in_browser, 184 bool check_in_browser,
185 sandbox::TargetPolicy* policy) { 185 sandbox::TargetPolicy* policy) {
186 HMODULE module = check_in_browser ? ::GetModuleHandleW(module_name) : NULL; 186 HMODULE module = check_in_browser ? ::GetModuleHandleW(module_name) : nullptr;
187 if (!module) { 187 if (!module) {
188 // The module could have been loaded with a 8.3 short name. We check 188 // The module could have been loaded with a 8.3 short name. We check
189 // the three most common cases: 'thelongname.dll' becomes 189 // the three most common cases: 'thelongname.dll' becomes
190 // 'thelon~1.dll', 'thelon~2.dll' and 'thelon~3.dll'. 190 // 'thelon~1.dll', 'thelon~2.dll' and 'thelon~3.dll'.
191 std::wstring name(module_name); 191 std::wstring name(module_name);
192 size_t period = name.rfind(L'.'); 192 size_t period = name.rfind(L'.');
193 DCHECK_NE(std::string::npos, period); 193 DCHECK_NE(std::string::npos, period);
194 DCHECK_LE(3U, (name.size() - period)); 194 DCHECK_LE(3U, (name.size() - period));
195 if (period <= 8) 195 if (period <= 8)
196 return; 196 return;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (!cmd_line.HasSwitch(switches::kAllowNoSandboxJob)) 249 if (!cmd_line.HasSwitch(switches::kAllowNoSandboxJob))
250 return true; 250 return true;
251 251
252 // Windows 8 allows nested jobs so we don't need to check if we are in other 252 // Windows 8 allows nested jobs so we don't need to check if we are in other
253 // job. 253 // job.
254 if (base::win::GetVersion() >= base::win::VERSION_WIN8) 254 if (base::win::GetVersion() >= base::win::VERSION_WIN8)
255 return true; 255 return true;
256 256
257 BOOL in_job = true; 257 BOOL in_job = true;
258 // Either there is no job yet associated so we must add our job, 258 // Either there is no job yet associated so we must add our job,
259 if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job)) 259 if (!::IsProcessInJob(::GetCurrentProcess(), nullptr, &in_job))
260 NOTREACHED() << "IsProcessInJob failed. " << GetLastError(); 260 NOTREACHED() << "IsProcessInJob failed. " << GetLastError();
261 if (!in_job) 261 if (!in_job)
262 return true; 262 return true;
263 263
264 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set. 264 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set.
265 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {0}; 265 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {0};
266 if (!::QueryInformationJobObject(NULL, 266 if (!::QueryInformationJobObject(nullptr,
267 JobObjectExtendedLimitInformation, &job_info, 267 JobObjectExtendedLimitInformation, &job_info,
268 sizeof(job_info), NULL)) { 268 sizeof(job_info), nullptr)) {
269 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); 269 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError();
270 return true; 270 return true;
271 } 271 }
272 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) 272 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK)
273 return true; 273 return true;
274 274
275 return false; 275 return false;
276 } 276 }
277 277
278 // Adds the generic policy rules to a sandbox TargetPolicy. 278 // Adds the generic policy rules to a sandbox TargetPolicy.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 typedef BOOL (WINAPI *DuplicateHandleFunctionPtr)(HANDLE source_process_handle, 409 typedef BOOL (WINAPI *DuplicateHandleFunctionPtr)(HANDLE source_process_handle,
410 HANDLE source_handle, 410 HANDLE source_handle,
411 HANDLE target_process_handle, 411 HANDLE target_process_handle,
412 LPHANDLE target_handle, 412 LPHANDLE target_handle,
413 DWORD desired_access, 413 DWORD desired_access,
414 BOOL inherit_handle, 414 BOOL inherit_handle,
415 DWORD options); 415 DWORD options);
416 416
417 DuplicateHandleFunctionPtr g_iat_orig_duplicate_handle; 417 DuplicateHandleFunctionPtr g_iat_orig_duplicate_handle;
418 418
419 NtQueryObject g_QueryObject = NULL; 419 NtQueryObject g_QueryObject = nullptr;
420 420
421 static const char* kDuplicateHandleWarning = 421 static const char* kDuplicateHandleWarning =
422 "You are attempting to duplicate a privileged handle into a sandboxed" 422 "You are attempting to duplicate a privileged handle into a sandboxed"
423 " process.\n Please use the sandbox::BrokerDuplicateHandle API or" 423 " process.\n Please use the sandbox::BrokerDuplicateHandle API or"
424 " contact security@chromium.org for assistance."; 424 " contact security@chromium.org for assistance.";
425 425
426 void CheckDuplicateHandle(HANDLE handle) { 426 void CheckDuplicateHandle(HANDLE handle) {
427 // Get the object type (32 characters is safe; current max is 14). 427 // Get the object type (32 characters is safe; current max is 14).
428 BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)]; 428 BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)];
429 OBJECT_TYPE_INFORMATION* type_info = 429 OBJECT_TYPE_INFORMATION* type_info =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 desired_access, inherit_handle, options)) 465 desired_access, inherit_handle, options))
466 return FALSE; 466 return FALSE;
467 467
468 // We're not worried about broker handles or not crossing process boundaries. 468 // We're not worried about broker handles or not crossing process boundaries.
469 if (source_process_handle == target_process_handle || 469 if (source_process_handle == target_process_handle ||
470 target_process_handle == ::GetCurrentProcess()) 470 target_process_handle == ::GetCurrentProcess())
471 return TRUE; 471 return TRUE;
472 472
473 // Only sandboxed children are placed in jobs, so just check them. 473 // Only sandboxed children are placed in jobs, so just check them.
474 BOOL is_in_job = FALSE; 474 BOOL is_in_job = FALSE;
475 if (!::IsProcessInJob(target_process_handle, NULL, &is_in_job)) { 475 if (!::IsProcessInJob(target_process_handle, nullptr, &is_in_job)) {
476 // We need a handle with permission to check the job object. 476 // We need a handle with permission to check the job object.
477 if (ERROR_ACCESS_DENIED == ::GetLastError()) { 477 if (ERROR_ACCESS_DENIED == ::GetLastError()) {
478 HANDLE temp_handle; 478 HANDLE temp_handle;
479 CHECK(g_iat_orig_duplicate_handle(::GetCurrentProcess(), 479 CHECK(g_iat_orig_duplicate_handle(::GetCurrentProcess(),
480 target_process_handle, 480 target_process_handle,
481 ::GetCurrentProcess(), 481 ::GetCurrentProcess(),
482 &temp_handle, 482 &temp_handle,
483 PROCESS_QUERY_INFORMATION, 483 PROCESS_QUERY_INFORMATION,
484 FALSE, 0)); 484 FALSE, 0));
485 base::win::ScopedHandle process(temp_handle); 485 base::win::ScopedHandle process(temp_handle);
486 CHECK(::IsProcessInJob(process.Get(), NULL, &is_in_job)); 486 CHECK(::IsProcessInJob(process.Get(), nullptr, &is_in_job));
487 } 487 }
488 } 488 }
489 489
490 if (is_in_job) { 490 if (is_in_job) {
491 // We never allow inheritable child handles. 491 // We never allow inheritable child handles.
492 CHECK(!inherit_handle) << kDuplicateHandleWarning; 492 CHECK(!inherit_handle) << kDuplicateHandleWarning;
493 493
494 // Duplicate the handle again, to get the final permissions. 494 // Duplicate the handle again, to get the final permissions.
495 HANDLE temp_handle; 495 HANDLE temp_handle;
496 CHECK(g_iat_orig_duplicate_handle(target_process_handle, *target_handle, 496 CHECK(g_iat_orig_duplicate_handle(target_process_handle, *target_handle,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 // TODO(abarth): DCHECK(CalledOnValidThread()); 535 // TODO(abarth): DCHECK(CalledOnValidThread());
536 // See <http://b/1287166>. 536 // See <http://b/1287166>.
537 DCHECK(broker_services); 537 DCHECK(broker_services);
538 DCHECK(!g_broker_services); 538 DCHECK(!g_broker_services);
539 sandbox::ResultCode result = broker_services->Init(); 539 sandbox::ResultCode result = broker_services->Init();
540 g_broker_services = broker_services; 540 g_broker_services = broker_services;
541 541
542 // In non-official builds warn about dangerous uses of DuplicateHandle. 542 // In non-official builds warn about dangerous uses of DuplicateHandle.
543 #ifndef OFFICIAL_BUILD 543 #ifndef OFFICIAL_BUILD
544 BOOL is_in_job = FALSE; 544 BOOL is_in_job = FALSE;
545 CHECK(::IsProcessInJob(::GetCurrentProcess(), NULL, &is_in_job)); 545 CHECK(::IsProcessInJob(::GetCurrentProcess(), nullptr, &is_in_job));
546 // In a Syzygy-profiled binary, instrumented for import profiling, this 546 // In a Syzygy-profiled binary, instrumented for import profiling, this
547 // patch will end in infinite recursion on the attempted delegation to the 547 // patch will end in infinite recursion on the attempted delegation to the
548 // original function. 548 // original function.
549 if (!base::debug::IsBinaryInstrumented() && 549 if (!base::debug::IsBinaryInstrumented() &&
550 !is_in_job && !g_iat_patch_duplicate_handle.is_patched()) { 550 !is_in_job && !g_iat_patch_duplicate_handle.is_patched()) {
551 HMODULE module = NULL; 551 HMODULE module = nullptr;
552 wchar_t module_name[MAX_PATH]; 552 wchar_t module_name[MAX_PATH];
553 CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, 553 CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
554 reinterpret_cast<LPCWSTR>(InitBrokerServices), 554 reinterpret_cast<LPCWSTR>(InitBrokerServices),
555 &module)); 555 &module));
556 DWORD result = ::GetModuleFileNameW(module, module_name, MAX_PATH); 556 DWORD result = ::GetModuleFileNameW(module, module_name, MAX_PATH);
557 if (result && (result != MAX_PATH)) { 557 if (result && (result != MAX_PATH)) {
558 ResolveNTFunctionPtr("NtQueryObject", &g_QueryObject); 558 ResolveNTFunctionPtr("NtQueryObject", &g_QueryObject);
559 result = g_iat_patch_duplicate_handle.Patch( 559 result = g_iat_patch_duplicate_handle.Patch(
560 module_name, "kernel32.dll", "DuplicateHandle", 560 module_name, "kernel32.dll", "DuplicateHandle",
561 DuplicateHandlePatch); 561 DuplicateHandlePatch);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 sandbox::MITIGATION_DEP | 649 sandbox::MITIGATION_DEP |
650 sandbox::MITIGATION_DEP_NO_ATL_THUNK | 650 sandbox::MITIGATION_DEP_NO_ATL_THUNK |
651 sandbox::MITIGATION_SEHOP; 651 sandbox::MITIGATION_SEHOP;
652 652
653 if (base::win::GetVersion() >= base::win::VERSION_WIN8 && 653 if (base::win::GetVersion() >= base::win::VERSION_WIN8 &&
654 type_str == switches::kRendererProcess && 654 type_str == switches::kRendererProcess &&
655 browser_command_line.HasSwitch( 655 browser_command_line.HasSwitch(
656 switches::kEnableWin32kRendererLockDown)) { 656 switches::kEnableWin32kRendererLockDown)) {
657 if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN, 657 if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
658 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, 658 sandbox::TargetPolicy::FAKE_USER_GDI_INIT,
659 NULL) != sandbox::SBOX_ALL_OK) { 659 nullptr) != sandbox::SBOX_ALL_OK) {
660 return 0; 660 return 0;
661 } 661 }
662 mitigations |= sandbox::MITIGATION_WIN32K_DISABLE; 662 mitigations |= sandbox::MITIGATION_WIN32K_DISABLE;
663 } 663 }
664 664
665 if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) 665 if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK)
666 return 0; 666 return 0;
667 667
668 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS | 668 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
669 sandbox::MITIGATION_DLL_SEARCH_ORDER; 669 sandbox::MITIGATION_DLL_SEARCH_ORDER;
670 670
671 if (policy->SetDelayedProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) 671 if (policy->SetDelayedProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK)
672 return 0; 672 return 0;
673 673
674 SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy); 674 SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy);
675 675
676 bool disable_default_policy = false; 676 bool disable_default_policy = false;
677 base::FilePath exposed_dir; 677 base::FilePath exposed_dir;
678 if (delegate) 678 if (delegate)
679 delegate->PreSandbox(&disable_default_policy, &exposed_dir); 679 delegate->PreSandbox(&disable_default_policy, &exposed_dir);
680 680
681 if (!disable_default_policy && !AddPolicyForSandboxedProcess(policy)) 681 if (!disable_default_policy && !AddPolicyForSandboxedProcess(policy))
682 return 0; 682 return 0;
683 683
684 if (type_str == switches::kRendererProcess) { 684 if (type_str == switches::kRendererProcess) {
685 if (ShouldUseDirectWrite()) { 685 if (ShouldUseDirectWrite()) {
686 AddDirectory(base::DIR_WINDOWS_FONTS, 686 AddDirectory(base::DIR_WINDOWS_FONTS,
687 NULL, 687 nullptr,
688 true, 688 true,
689 sandbox::TargetPolicy::FILES_ALLOW_READONLY, 689 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
690 policy); 690 policy);
691 } 691 }
692 } else { 692 } else {
693 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into 693 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into
694 // this subprocess. See 694 // this subprocess. See
695 // http://code.google.com/p/chromium/issues/detail?id=25580 695 // http://code.google.com/p/chromium/issues/detail?id=25580
696 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); 696 cmd_line->AppendSwitchASCII("ignored", " --type=renderer ");
697 } 697 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 791 }
792 792
793 return false; 793 return false;
794 } 794 }
795 795
796 bool BrokerAddTargetPeer(HANDLE peer_process) { 796 bool BrokerAddTargetPeer(HANDLE peer_process) {
797 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; 797 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK;
798 } 798 }
799 799
800 } // namespace content 800 } // namespace content
OLDNEW
« no previous file with comments | « content/common/sandbox_mac_unittest_helper.h ('k') | content/common/savable_url_schemes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698