Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 sizeof(session_id), &session_id_length)); | 243 sizeof(session_id), &session_id_length)); |
| 244 CloseHandle(token); | 244 CloseHandle(token); |
| 245 if (session_id) | 245 if (session_id) |
| 246 s_session_id = session_id; | 246 s_session_id = session_id; |
| 247 } | 247 } |
| 248 | 248 |
| 249 return base::StringPrintf(L"\\Sessions\\%lu%ls", s_session_id, object); | 249 return base::StringPrintf(L"\\Sessions\\%lu%ls", s_session_id, object); |
| 250 } | 250 } |
| 251 | 251 |
| 252 // Checks if the sandbox should be let to run without a job object assigned. | 252 // Checks if the sandbox should be let to run without a job object assigned. |
| 253 bool ShouldSetJobLevel(const base::CommandLine& cmd_line) { | 253 bool ShouldSetJobLevel() { |
| 254 if (!cmd_line.HasSwitch(switches::kAllowNoSandboxJob)) | |
| 255 return true; | |
| 256 | |
| 257 // Windows 8 allows nested jobs so we don't need to check if we are in other | 254 // Windows 8 allows nested jobs so we don't need to check if we are in other |
| 258 // job. | 255 // job. |
| 259 if (base::win::GetVersion() >= base::win::VERSION_WIN8) | 256 if (base::win::GetVersion() >= base::win::VERSION_WIN8) |
| 260 return true; | 257 return true; |
| 261 | 258 |
| 262 BOOL in_job = true; | 259 BOOL in_job = true; |
| 263 // Either there is no job yet associated so we must add our job, | 260 // Either there is no job yet associated so we must add our job, |
| 264 if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job)) | 261 if (!::IsProcessInJob(::GetCurrentProcess(), NULL, &in_job)) |
| 265 NOTREACHED() << "IsProcessInJob failed. " << GetLastError(); | 262 NOTREACHED() << "IsProcessInJob failed. " << GetLastError(); |
| 266 if (!in_job) | 263 if (!in_job) |
| 267 return true; | 264 return true; |
| 268 | 265 |
| 269 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set. | 266 // ...or there is a job but the JOB_OBJECT_LIMIT_BREAKAWAY_OK limit is set. |
| 270 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {}; | 267 JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = {}; |
| 271 if (!::QueryInformationJobObject(NULL, | 268 if (!::QueryInformationJobObject(NULL, |
| 272 JobObjectExtendedLimitInformation, &job_info, | 269 JobObjectExtendedLimitInformation, &job_info, |
| 273 sizeof(job_info), NULL)) { | 270 sizeof(job_info), NULL)) { |
| 274 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); | 271 NOTREACHED() << "QueryInformationJobObject failed. " << GetLastError(); |
| 275 return true; | 272 return true; |
| 276 } | 273 } |
| 277 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) | 274 if (job_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK) |
| 278 return true; | 275 return true; |
| 279 | 276 |
| 277 // Lastly in place of the flag which was supposed to be used only for running | |
| 278 // Chrome in remote sessions we do this check explicitly here. | |
| 279 // According to MS this flag can be false for a remote session only on Windows | |
|
Will Harris
2017/02/03 17:38:50
can you link the source?
pastarmovj
2017/02/06 13:05:27
Done.
| |
| 280 // Server 2012 and newer so if we do the check last we should be on the safe | |
|
Will Harris
2017/02/03 17:38:50
we can't just check for this version of OS instead
pastarmovj
2017/02/06 13:05:27
Not sure what do you mean? What I am trying to say
| |
| 281 // side. | |
| 282 if (!::GetSystemMetrics(SM_REMOTESESSION)) | |
|
Will Harris
2017/02/03 17:38:50
how is this tested? is there a set of automated te
pastarmovj
2017/02/06 13:05:27
This is something I will start another thread abou
| |
| 283 return true; | |
| 284 | |
| 285 // Allow running without the sandbox in this case. This slightly reduces the | |
| 286 // ability of the sandbox to protect its children from spawning new processes | |
| 287 // or preventing them from shutting down Windows or accessing the clipboard. | |
| 280 return false; | 288 return false; |
| 281 } | 289 } |
| 282 | 290 |
| 283 // Adds the generic policy rules to a sandbox TargetPolicy. | 291 // Adds the generic policy rules to a sandbox TargetPolicy. |
| 284 sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) { | 292 sandbox::ResultCode AddGenericPolicy(sandbox::TargetPolicy* policy) { |
| 285 sandbox::ResultCode result; | 293 sandbox::ResultCode result; |
| 286 | 294 |
| 287 // Add the policy for the client side of a pipe. It is just a file | 295 // 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 | 296 // in the \pipe\ namespace. We restrict it to pipes that start with |
| 289 // "chrome." so the sandboxed process cannot connect to system services. | 297 // "chrome." so the sandboxed process cannot connect to system services. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 if (command_line.HasSwitch(switches::kDisableAppContainer)) | 567 if (command_line.HasSwitch(switches::kDisableAppContainer)) |
| 560 return false; | 568 return false; |
| 561 if (command_line.HasSwitch(switches::kEnableAppContainer)) | 569 if (command_line.HasSwitch(switches::kEnableAppContainer)) |
| 562 return true; | 570 return true; |
| 563 return base::StartsWith(appcontainer_group_name, "Enabled", | 571 return base::StartsWith(appcontainer_group_name, "Enabled", |
| 564 base::CompareCase::INSENSITIVE_ASCII); | 572 base::CompareCase::INSENSITIVE_ASCII); |
| 565 } | 573 } |
| 566 | 574 |
| 567 } // namespace | 575 } // namespace |
| 568 | 576 |
| 569 sandbox::ResultCode SetJobLevel(const base::CommandLine& cmd_line, | 577 sandbox::ResultCode SetJobLevel(sandbox::JobLevel job_level, |
| 570 sandbox::JobLevel job_level, | |
| 571 uint32_t ui_exceptions, | 578 uint32_t ui_exceptions, |
| 572 sandbox::TargetPolicy* policy) { | 579 sandbox::TargetPolicy* policy) { |
| 573 if (!ShouldSetJobLevel(cmd_line)) | 580 if (!ShouldSetJobLevel()) |
| 574 return policy->SetJobLevel(sandbox::JOB_NONE, 0); | 581 return policy->SetJobLevel(sandbox::JOB_NONE, 0); |
| 575 | 582 |
| 576 #ifdef _WIN64 | 583 #ifdef _WIN64 |
| 577 sandbox::ResultCode ret = | 584 sandbox::ResultCode ret = |
| 578 policy->SetJobMemoryLimit(4ULL * 1024 * 1024 * 1024); | 585 policy->SetJobMemoryLimit(4ULL * 1024 * 1024 * 1024); |
| 579 if (ret != sandbox::SBOX_ALL_OK) | 586 if (ret != sandbox::SBOX_ALL_OK) |
| 580 return ret; | 587 return ret; |
| 581 #endif | 588 #endif |
| 582 return policy->SetJobLevel(job_level, ui_exceptions); | 589 return policy->SetJobLevel(job_level, ui_exceptions); |
| 583 } | 590 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 base::CommandLine* cmd_line, | 684 base::CommandLine* cmd_line, |
| 678 const base::HandlesToInheritVector& handles_to_inherit, | 685 const base::HandlesToInheritVector& handles_to_inherit, |
| 679 base::Process* process) { | 686 base::Process* process) { |
| 680 DCHECK(delegate); | 687 DCHECK(delegate); |
| 681 const base::CommandLine& browser_command_line = | 688 const base::CommandLine& browser_command_line = |
| 682 *base::CommandLine::ForCurrentProcess(); | 689 *base::CommandLine::ForCurrentProcess(); |
| 683 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 690 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 684 | 691 |
| 685 TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str); | 692 TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str); |
| 686 | 693 |
| 687 // Propagate the --allow-no-job flag if present. | |
| 688 if (browser_command_line.HasSwitch(switches::kAllowNoSandboxJob) && | |
| 689 !cmd_line->HasSwitch(switches::kAllowNoSandboxJob)) { | |
| 690 cmd_line->AppendSwitch(switches::kAllowNoSandboxJob); | |
| 691 } | |
| 692 | |
| 693 ProcessDebugFlags(cmd_line); | 694 ProcessDebugFlags(cmd_line); |
| 694 | 695 |
| 695 if ((!delegate->ShouldSandbox()) || | 696 if ((!delegate->ShouldSandbox()) || |
| 696 browser_command_line.HasSwitch(switches::kNoSandbox) || | 697 browser_command_line.HasSwitch(switches::kNoSandbox) || |
| 697 cmd_line->HasSwitch(switches::kNoSandbox)) { | 698 cmd_line->HasSwitch(switches::kNoSandbox)) { |
| 698 base::LaunchOptions options; | 699 base::LaunchOptions options; |
| 699 | 700 |
| 700 base::HandlesToInheritVector handles = handles_to_inherit; | 701 base::HandlesToInheritVector handles = handles_to_inherit; |
| 701 if (!handles_to_inherit.empty()) { | 702 if (!handles_to_inherit.empty()) { |
| 702 options.inherit_handles = true; | 703 options.inherit_handles = true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 743 #endif | 744 #endif |
| 744 | 745 |
| 745 // Post-startup mitigations. | 746 // Post-startup mitigations. |
| 746 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS | | 747 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS | |
| 747 sandbox::MITIGATION_DLL_SEARCH_ORDER; | 748 sandbox::MITIGATION_DLL_SEARCH_ORDER; |
| 748 | 749 |
| 749 result = policy->SetDelayedProcessMitigations(mitigations); | 750 result = policy->SetDelayedProcessMitigations(mitigations); |
| 750 if (result != sandbox::SBOX_ALL_OK) | 751 if (result != sandbox::SBOX_ALL_OK) |
| 751 return result; | 752 return result; |
| 752 | 753 |
| 753 result = SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy); | 754 result = SetJobLevel(sandbox::JOB_LOCKDOWN, 0, policy); |
| 754 if (result != sandbox::SBOX_ALL_OK) | 755 if (result != sandbox::SBOX_ALL_OK) |
| 755 return result; | 756 return result; |
| 756 | 757 |
| 757 if (!delegate->DisableDefaultPolicy()) { | 758 if (!delegate->DisableDefaultPolicy()) { |
| 758 result = AddPolicyForSandboxedProcess(policy); | 759 result = AddPolicyForSandboxedProcess(policy); |
| 759 if (result != sandbox::SBOX_ALL_OK) | 760 if (result != sandbox::SBOX_ALL_OK) |
| 760 return result; | 761 return result; |
| 761 } | 762 } |
| 762 | 763 |
| 763 #if !defined(NACL_WIN64) | 764 #if !defined(NACL_WIN64) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 832 } | 833 } |
| 833 | 834 |
| 834 delegate->PostSpawnTarget(target.process_handle()); | 835 delegate->PostSpawnTarget(target.process_handle()); |
| 835 | 836 |
| 836 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1)); | 837 CHECK(ResumeThread(target.thread_handle()) != static_cast<DWORD>(-1)); |
| 837 *process = base::Process(target.TakeProcessHandle()); | 838 *process = base::Process(target.TakeProcessHandle()); |
| 838 return sandbox::SBOX_ALL_OK; | 839 return sandbox::SBOX_ALL_OK; |
| 839 } | 840 } |
| 840 | 841 |
| 841 } // namespace content | 842 } // namespace content |
| OLD | NEW |