123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "sandbox/win/src/startup_information_helper.h"
- #include <Windows.h>
- #include <algorithm>
- #include <vector>
- #include "base/check.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/win/startup_information.h"
- #include "base/win/windows_version.h"
- #include "sandbox/win/src/app_container.h"
- #include "sandbox/win/src/nt_internals.h"
- #include "sandbox/win/src/security_capabilities.h"
- #include "sandbox/win/src/win_utils.h"
- namespace sandbox {
- using base::win::StartupInformation;
- StartupInformationHelper::StartupInformationHelper() {}
- StartupInformationHelper::~StartupInformationHelper() {}
- void StartupInformationHelper::UpdateFlags(DWORD flags) {
- startup_info_.startup_info()->dwFlags |= flags;
- }
- void StartupInformationHelper::SetDesktop(std::wstring desktop) {
- desktop_ = desktop;
- if (!desktop_.empty()) {
- startup_info_.startup_info()->lpDesktop =
- const_cast<wchar_t*>(desktop_.c_str());
- } else {
- startup_info_.startup_info()->lpDesktop = nullptr;
- }
- }
- void StartupInformationHelper::SetMitigations(MitigationFlags flags) {
- ConvertProcessMitigationsToPolicy(flags, &mitigations_[0],
- &mitigations_size_);
- ConvertProcessMitigationsToComponentFilter(flags, &component_filter_);
- }
- void StartupInformationHelper::SetRestrictChildProcessCreation(bool restrict) {
- DCHECK(base::win::GetVersion() >= base::win::Version::WIN10_TH2);
- restrict_child_process_creation_ = restrict;
- }
- void StartupInformationHelper::SetStdHandles(HANDLE stdout_handle,
- HANDLE stderr_handle) {
- stdout_handle_ = stdout_handle;
- AddInheritedHandle(stdout_handle);
- stderr_handle_ = stderr_handle;
- if (stderr_handle != stdout_handle)
- AddInheritedHandle(stderr_handle);
- }
- void StartupInformationHelper::AddInheritedHandle(HANDLE handle) {
- if (handle != INVALID_HANDLE_VALUE) {
- auto it = std::find(inherited_handle_list_.begin(),
- inherited_handle_list_.end(), handle);
- if (it == inherited_handle_list_.end())
- inherited_handle_list_.push_back(handle);
- }
- }
- void StartupInformationHelper::SetAppContainer(
- scoped_refptr<AppContainer> container) {
- // Only supported for Windows 8+.
- DCHECK(base::win::GetVersion() >= base::win::Version::WIN8);
- // LowPrivilegeAppContainer only supported for Windows 10+
- DCHECK(!container->GetEnableLowPrivilegeAppContainer() ||
- base::win::GetVersion() >= base::win::Version::WIN10_RS1);
- app_container_ = container;
- security_capabilities_ = app_container_->GetSecurityCapabilities();
- }
- void StartupInformationHelper::AddJobToAssociate(HANDLE job_handle) {
- job_handle_list_.push_back(job_handle);
- }
- int StartupInformationHelper::CountAttributes() {
- int attribute_count = 0;
- if (mitigations_[0] || mitigations_[1])
- ++attribute_count;
- if (component_filter_.ComponentFlags)
- ++attribute_count;
- if (restrict_child_process_creation_)
- ++attribute_count;
- if (!inherited_handle_list_.empty())
- ++attribute_count;
- if (app_container_ &&
- app_container_->GetAppContainerType() != AppContainerType::kLowbox) {
- ++attribute_count;
- if (app_container_->GetEnableLowPrivilegeAppContainer())
- ++attribute_count;
- }
- if (!job_handle_list_.empty())
- ++attribute_count;
- return attribute_count;
- }
- bool StartupInformationHelper::BuildStartupInformation() {
- // When adding new attributes, any memory referenced needs to have the
- // same lifetime as startup_info_. This is why we use members below.
- auto expected_attributes = CountAttributes();
- if (!startup_info_.InitializeProcThreadAttributeList(expected_attributes))
- return false;
- if (mitigations_[0] || mitigations_[1]) {
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &mitigations_[0],
- mitigations_size_)) {
- return false;
- }
- expected_attributes--;
- }
- if (component_filter_.ComponentFlags) {
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_COMPONENT_FILTER, &component_filter_,
- sizeof(component_filter_)) &&
- ::GetLastError() != ERROR_NOT_SUPPORTED) {
- return false;
- }
- expected_attributes--;
- }
- if (restrict_child_process_creation_) {
- child_process_creation_ = PROCESS_CREATION_CHILD_PROCESS_RESTRICTED;
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY,
- &child_process_creation_, sizeof(child_process_creation_))) {
- return false;
- }
- expected_attributes--;
- }
- if (inherited_handle_list_.size()) {
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &inherited_handle_list_[0],
- sizeof(HANDLE) * inherited_handle_list_.size())) {
- return false;
- }
- startup_info_.startup_info()->dwFlags |= STARTF_USESTDHANDLES;
- startup_info_.startup_info()->hStdInput = INVALID_HANDLE_VALUE;
- startup_info_.startup_info()->hStdOutput = stdout_handle_;
- startup_info_.startup_info()->hStdError = stderr_handle_;
- // Allowing inheritance of handles is only secure now that we
- // have limited which handles will be inherited.
- inherit_handles_ = true;
- expected_attributes--;
- }
- if (!job_handle_list_.empty()) {
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_JOB_LIST, &job_handle_list_[0],
- sizeof(HANDLE) * job_handle_list_.size())) {
- return false;
- }
- expected_attributes--;
- }
- if (app_container_ &&
- app_container_->GetAppContainerType() != AppContainerType::kLowbox) {
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES,
- security_capabilities_.get(), sizeof(SECURITY_CAPABILITIES))) {
- return false;
- }
- expected_attributes--;
- if (app_container_->GetEnableLowPrivilegeAppContainer()) {
- all_applications_package_policy_ =
- PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT;
- if (!startup_info_.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY,
- &all_applications_package_policy_,
- sizeof(all_applications_package_policy_))) {
- return false;
- }
- expected_attributes--;
- }
- }
- CHECK(expected_attributes == 0);
- return true;
- }
- } // namespace sandbox
|