Index: sandbox/win/src/sandbox_policy_base.cc |
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc |
deleted file mode 100644 |
index a3af98d3bbbd01a85801c70f21e1c2de9df1e491..0000000000000000000000000000000000000000 |
--- a/sandbox/win/src/sandbox_policy_base.cc |
+++ /dev/null |
@@ -1,777 +0,0 @@ |
-// Copyright (c) 2012 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/sandbox_policy_base.h" |
- |
-#include <sddl.h> |
-#include <stddef.h> |
-#include <stdint.h> |
- |
-#include "base/callback.h" |
-#include "base/logging.h" |
-#include "base/macros.h" |
-#include "base/stl_util.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/win/windows_version.h" |
-#include "sandbox/win/src/app_container.h" |
-#include "sandbox/win/src/filesystem_policy.h" |
-#include "sandbox/win/src/handle_policy.h" |
-#include "sandbox/win/src/interception.h" |
-#include "sandbox/win/src/job.h" |
-#include "sandbox/win/src/named_pipe_policy.h" |
-#include "sandbox/win/src/policy_broker.h" |
-#include "sandbox/win/src/policy_engine_processor.h" |
-#include "sandbox/win/src/policy_low_level.h" |
-#include "sandbox/win/src/process_mitigations.h" |
-#include "sandbox/win/src/process_mitigations_win32k_policy.h" |
-#include "sandbox/win/src/process_thread_policy.h" |
-#include "sandbox/win/src/registry_policy.h" |
-#include "sandbox/win/src/restricted_token_utils.h" |
-#include "sandbox/win/src/sandbox_policy.h" |
-#include "sandbox/win/src/sandbox_utils.h" |
-#include "sandbox/win/src/sync_policy.h" |
-#include "sandbox/win/src/target_process.h" |
-#include "sandbox/win/src/top_level_dispatcher.h" |
-#include "sandbox/win/src/window.h" |
- |
-namespace { |
- |
-// The standard windows size for one memory page. |
-const size_t kOneMemPage = 4096; |
-// The IPC and Policy shared memory sizes. |
-const size_t kIPCMemSize = kOneMemPage * 2; |
-const size_t kPolMemSize = kOneMemPage * 14; |
- |
-// Helper function to allocate space (on the heap) for policy. |
-sandbox::PolicyGlobal* MakeBrokerPolicyMemory() { |
- const size_t kTotalPolicySz = kPolMemSize; |
- sandbox::PolicyGlobal* policy = static_cast<sandbox::PolicyGlobal*> |
- (::operator new(kTotalPolicySz)); |
- DCHECK(policy); |
- memset(policy, 0, kTotalPolicySz); |
- policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal); |
- return policy; |
-} |
- |
-bool IsInheritableHandle(HANDLE handle) { |
- if (!handle) |
- return false; |
- if (handle == INVALID_HANDLE_VALUE) |
- return false; |
- // File handles (FILE_TYPE_DISK) and pipe handles are known to be |
- // inheritable. Console handles (FILE_TYPE_CHAR) are not |
- // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST. |
- DWORD handle_type = GetFileType(handle); |
- return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; |
-} |
- |
-HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) { |
- DWORD session_id = 0; |
- if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) |
- return NULL; |
- |
- LPWSTR sid_string = NULL; |
- if (!::ConvertSidToStringSid(lowbox_sid, &sid_string)) |
- return NULL; |
- |
- base::string16 directory_path = base::StringPrintf( |
- L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls", |
- session_id, sid_string).c_str(); |
- ::LocalFree(sid_string); |
- |
- NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL; |
- ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory); |
- |
- OBJECT_ATTRIBUTES obj_attr; |
- UNICODE_STRING obj_name; |
- sandbox::InitObjectAttribs(directory_path, |
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF, |
- NULL, |
- &obj_attr, |
- &obj_name, |
- NULL); |
- |
- HANDLE handle = NULL; |
- NTSTATUS status = CreateObjectDirectory(&handle, |
- DIRECTORY_ALL_ACCESS, |
- &obj_attr); |
- |
- if (!NT_SUCCESS(status)) |
- return NULL; |
- |
- return handle; |
-} |
- |
-} // namespace |
- |
-namespace sandbox { |
- |
-SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; |
-SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; |
- |
-// Initializes static members. |
-HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; |
-HDESK PolicyBase::alternate_desktop_handle_ = NULL; |
-IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = |
- INTEGRITY_LEVEL_SYSTEM; |
- |
-PolicyBase::PolicyBase() |
- : ref_count(1), |
- lockdown_level_(USER_LOCKDOWN), |
- initial_level_(USER_LOCKDOWN), |
- job_level_(JOB_LOCKDOWN), |
- ui_exceptions_(0), |
- memory_limit_(0), |
- use_alternate_desktop_(false), |
- use_alternate_winstation_(false), |
- file_system_init_(false), |
- relaxed_interceptions_(true), |
- stdout_handle_(INVALID_HANDLE_VALUE), |
- stderr_handle_(INVALID_HANDLE_VALUE), |
- integrity_level_(INTEGRITY_LEVEL_LAST), |
- delayed_integrity_level_(INTEGRITY_LEVEL_LAST), |
- mitigations_(0), |
- delayed_mitigations_(0), |
- is_csrss_connected_(true), |
- policy_maker_(NULL), |
- policy_(NULL), |
- lowbox_sid_(NULL), |
- lockdown_default_dacl_(false) { |
- ::InitializeCriticalSection(&lock_); |
- dispatcher_.reset(new TopLevelDispatcher(this)); |
-} |
- |
-PolicyBase::~PolicyBase() { |
- TargetSet::iterator it; |
- for (it = targets_.begin(); it != targets_.end(); ++it) { |
- TargetProcess* target = (*it); |
- delete target; |
- } |
- delete policy_maker_; |
- delete policy_; |
- |
- if (lowbox_sid_) |
- ::LocalFree(lowbox_sid_); |
- |
- ::DeleteCriticalSection(&lock_); |
-} |
- |
-void PolicyBase::AddRef() { |
- ::InterlockedIncrement(&ref_count); |
-} |
- |
-void PolicyBase::Release() { |
- if (0 == ::InterlockedDecrement(&ref_count)) |
- delete this; |
-} |
- |
-ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) { |
- if (initial < lockdown) { |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- initial_level_ = initial; |
- lockdown_level_ = lockdown; |
- return SBOX_ALL_OK; |
-} |
- |
-TokenLevel PolicyBase::GetInitialTokenLevel() const { |
- return initial_level_; |
-} |
- |
-TokenLevel PolicyBase::GetLockdownTokenLevel() const { |
- return lockdown_level_; |
-} |
- |
-ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32_t ui_exceptions) { |
- if (memory_limit_ && job_level == JOB_NONE) { |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- job_level_ = job_level; |
- ui_exceptions_ = ui_exceptions; |
- return SBOX_ALL_OK; |
-} |
- |
-JobLevel PolicyBase::GetJobLevel() const { |
- return job_level_; |
-} |
- |
-ResultCode PolicyBase::SetJobMemoryLimit(size_t memory_limit) { |
- if (memory_limit && job_level_ == JOB_NONE) { |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- memory_limit_ = memory_limit; |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) { |
- use_alternate_desktop_ = true; |
- use_alternate_winstation_ = alternate_winstation; |
- return CreateAlternateDesktop(alternate_winstation); |
-} |
- |
-base::string16 PolicyBase::GetAlternateDesktop() const { |
- // No alternate desktop or winstation. Return an empty string. |
- if (!use_alternate_desktop_ && !use_alternate_winstation_) { |
- return base::string16(); |
- } |
- |
- // The desktop and winstation should have been created by now. |
- // If we hit this scenario, it means that the user ignored the failure |
- // during SetAlternateDesktop, so we ignore it here too. |
- if (use_alternate_desktop_ && !alternate_desktop_handle_) { |
- return base::string16(); |
- } |
- if (use_alternate_winstation_ && (!alternate_desktop_handle_ || |
- !alternate_winstation_handle_)) { |
- return base::string16(); |
- } |
- |
- return GetFullDesktopName(alternate_winstation_handle_, |
- alternate_desktop_handle_); |
-} |
- |
-ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) { |
- if (alternate_winstation) { |
- // Previously called with alternate_winstation = false? |
- if (!alternate_winstation_handle_ && alternate_desktop_handle_) |
- return SBOX_ERROR_UNSUPPORTED; |
- |
- // Check if it's already created. |
- if (alternate_winstation_handle_ && alternate_desktop_handle_) |
- return SBOX_ALL_OK; |
- |
- DCHECK(!alternate_winstation_handle_); |
- // Create the window station. |
- ResultCode result = CreateAltWindowStation(&alternate_winstation_handle_); |
- if (SBOX_ALL_OK != result) |
- return result; |
- |
- // Verify that everything is fine. |
- if (!alternate_winstation_handle_ || |
- GetWindowObjectName(alternate_winstation_handle_).empty()) |
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
- |
- // Create the destkop. |
- result = CreateAltDesktop(alternate_winstation_handle_, |
- &alternate_desktop_handle_); |
- if (SBOX_ALL_OK != result) |
- return result; |
- |
- // Verify that everything is fine. |
- if (!alternate_desktop_handle_ || |
- GetWindowObjectName(alternate_desktop_handle_).empty()) |
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
- } else { |
- // Previously called with alternate_winstation = true? |
- if (alternate_winstation_handle_) |
- return SBOX_ERROR_UNSUPPORTED; |
- |
- // Check if it already exists. |
- if (alternate_desktop_handle_) |
- return SBOX_ALL_OK; |
- |
- // Create the destkop. |
- ResultCode result = CreateAltDesktop(NULL, &alternate_desktop_handle_); |
- if (SBOX_ALL_OK != result) |
- return result; |
- |
- // Verify that everything is fine. |
- if (!alternate_desktop_handle_ || |
- GetWindowObjectName(alternate_desktop_handle_).empty()) |
- return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
- } |
- |
- return SBOX_ALL_OK; |
-} |
- |
-void PolicyBase::DestroyAlternateDesktop() { |
- if (alternate_desktop_handle_) { |
- ::CloseDesktop(alternate_desktop_handle_); |
- alternate_desktop_handle_ = NULL; |
- } |
- |
- if (alternate_winstation_handle_) { |
- ::CloseWindowStation(alternate_winstation_handle_); |
- alternate_winstation_handle_ = NULL; |
- } |
-} |
- |
-ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) { |
- integrity_level_ = integrity_level; |
- return SBOX_ALL_OK; |
-} |
- |
-IntegrityLevel PolicyBase::GetIntegrityLevel() const { |
- return integrity_level_; |
-} |
- |
-ResultCode PolicyBase::SetDelayedIntegrityLevel( |
- IntegrityLevel integrity_level) { |
- delayed_integrity_level_ = integrity_level; |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { |
- if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) |
- return SBOX_ALL_OK; |
- |
- // SetLowBox and SetAppContainer are mutually exclusive. |
- if (lowbox_sid_) |
- return SBOX_ERROR_UNSUPPORTED; |
- |
- // Windows refuses to work with an impersonation token for a process inside |
- // an AppContainer. If the caller wants to use a more privileged initial |
- // token, or if the lockdown level will prevent the process from starting, |
- // we have to fail the operation. |
- if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) |
- return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; |
- |
- DCHECK(!appcontainer_list_.get()); |
- appcontainer_list_.reset(new AppContainerAttributes); |
- ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); |
- if (rv != SBOX_ALL_OK) |
- return rv; |
- |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetCapability(const wchar_t* sid) { |
- capabilities_.push_back(sid); |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { |
- if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) |
- return SBOX_ERROR_UNSUPPORTED; |
- |
- // SetLowBox and SetAppContainer are mutually exclusive. |
- if (appcontainer_list_.get()) |
- return SBOX_ERROR_UNSUPPORTED; |
- |
- DCHECK(sid); |
- |
- if (lowbox_sid_) |
- return SBOX_ERROR_BAD_PARAMS; |
- |
- if (!ConvertStringSidToSid(sid, &lowbox_sid_)) |
- return SBOX_ERROR_GENERIC; |
- |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetProcessMitigations( |
- MitigationFlags flags) { |
- if (!CanSetProcessMitigationsPreStartup(flags)) |
- return SBOX_ERROR_BAD_PARAMS; |
- mitigations_ = flags; |
- return SBOX_ALL_OK; |
-} |
- |
-MitigationFlags PolicyBase::GetProcessMitigations() { |
- return mitigations_; |
-} |
- |
-ResultCode PolicyBase::SetDelayedProcessMitigations( |
- MitigationFlags flags) { |
- if (!CanSetProcessMitigationsPostStartup(flags)) |
- return SBOX_ERROR_BAD_PARAMS; |
- delayed_mitigations_ = flags; |
- return SBOX_ALL_OK; |
-} |
- |
-MitigationFlags PolicyBase::GetDelayedProcessMitigations() const { |
- return delayed_mitigations_; |
-} |
- |
-void PolicyBase::SetStrictInterceptions() { |
- relaxed_interceptions_ = false; |
-} |
- |
-ResultCode PolicyBase::SetStdoutHandle(HANDLE handle) { |
- if (!IsInheritableHandle(handle)) |
- return SBOX_ERROR_BAD_PARAMS; |
- stdout_handle_ = handle; |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::SetStderrHandle(HANDLE handle) { |
- if (!IsInheritableHandle(handle)) |
- return SBOX_ERROR_BAD_PARAMS; |
- stderr_handle_ = handle; |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::AddRule(SubSystem subsystem, |
- Semantics semantics, |
- const wchar_t* pattern) { |
- ResultCode result = AddRuleInternal(subsystem, semantics, pattern); |
- LOG_IF(ERROR, result != SBOX_ALL_OK) << "Failed to add sandbox rule." |
- << " error = " << result |
- << ", subsystem = " << subsystem |
- << ", semantics = " << semantics |
- << ", pattern = '" << pattern << "'"; |
- return result; |
-} |
- |
-ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) { |
- blacklisted_dlls_.push_back(dll_name); |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::AddKernelObjectToClose(const base::char16* handle_type, |
- const base::char16* handle_name) { |
- return handle_closer_.AddHandle(handle_type, handle_name); |
-} |
- |
-void PolicyBase::AddHandleToShare(HANDLE handle) { |
- CHECK(handle && handle != INVALID_HANDLE_VALUE); |
- |
- // Ensure the handle can be inherited. |
- BOOL result = SetHandleInformation(handle, HANDLE_FLAG_INHERIT, |
- HANDLE_FLAG_INHERIT); |
- PCHECK(result); |
- |
- handles_to_share_.push_back(handle); |
-} |
- |
-void PolicyBase::SetLockdownDefaultDacl() { |
- lockdown_default_dacl_ = true; |
-} |
- |
-const base::HandlesToInheritVector& PolicyBase::GetHandlesBeingShared() { |
- return handles_to_share_; |
-} |
- |
-ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { |
- if (job_level_ != JOB_NONE) { |
- // Create the windows job object. |
- Job job_obj; |
- DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_, |
- memory_limit_); |
- if (ERROR_SUCCESS != result) |
- return SBOX_ERROR_GENERIC; |
- |
- *job = job_obj.Take(); |
- } else { |
- *job = base::win::ScopedHandle(); |
- } |
- return SBOX_ALL_OK; |
-} |
- |
-ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, |
- base::win::ScopedHandle* lockdown, |
- base::win::ScopedHandle* lowbox) { |
- if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && |
- lowbox_sid_) { |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- |
- // Create the 'naked' token. This will be the permanent token associated |
- // with the process and therefore with any thread that is not impersonating. |
- DWORD result = |
- CreateRestrictedToken(lockdown_level_, integrity_level_, PRIMARY, |
- lockdown_default_dacl_, lockdown); |
- if (ERROR_SUCCESS != result) |
- return SBOX_ERROR_GENERIC; |
- |
- // If we're launching on the alternate desktop we need to make sure the |
- // integrity label on the object is no higher than the sandboxed process's |
- // integrity level. So, we lower the label on the desktop process if it's |
- // not already low enough for our process. |
- if (alternate_desktop_handle_ && use_alternate_desktop_ && |
- integrity_level_ != INTEGRITY_LEVEL_LAST && |
- alternate_desktop_integrity_level_label_ < integrity_level_) { |
- // Integrity label enum is reversed (higher level is a lower value). |
- static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
- "Integrity level ordering reversed."); |
- result = SetObjectIntegrityLabel(alternate_desktop_handle_, |
- SE_WINDOW_OBJECT, |
- L"", |
- GetIntegrityLevelString(integrity_level_)); |
- if (ERROR_SUCCESS != result) |
- return SBOX_ERROR_GENERIC; |
- |
- alternate_desktop_integrity_level_label_ = integrity_level_; |
- } |
- |
- // We are maintaining two mutually exclusive approaches. One is to start an |
- // AppContainer process through StartupInfoEx and other is replacing |
- // existing token with LowBox token after process creation. |
- if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { |
- // Windows refuses to work with an impersonation token. See SetAppContainer |
- // implementation for more details. |
- if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) |
- return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; |
- |
- *initial = base::win::ScopedHandle(); |
- return SBOX_ALL_OK; |
- } |
- |
- if (lowbox_sid_) { |
- NtCreateLowBoxToken CreateLowBoxToken = NULL; |
- ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken); |
- OBJECT_ATTRIBUTES obj_attr; |
- InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); |
- HANDLE token_lowbox = NULL; |
- |
- if (!lowbox_directory_.IsValid()) |
- lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); |
- DCHECK(lowbox_directory_.IsValid()); |
- |
- // The order of handles isn't important in the CreateLowBoxToken call. |
- // The kernel will maintain a reference to the object directory handle. |
- HANDLE saved_handles[1] = {lowbox_directory_.Get()}; |
- DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; |
- |
- NTSTATUS status = CreateLowBoxToken(&token_lowbox, lockdown->Get(), |
- TOKEN_ALL_ACCESS, &obj_attr, |
- lowbox_sid_, 0, NULL, |
- saved_handles_count, saved_handles); |
- if (!NT_SUCCESS(status)) |
- return SBOX_ERROR_GENERIC; |
- |
- DCHECK(token_lowbox); |
- lowbox->Set(token_lowbox); |
- } |
- |
- // Create the 'better' token. We use this token as the one that the main |
- // thread uses when booting up the process. It should contain most of |
- // what we need (before reaching main( )) |
- result = |
- CreateRestrictedToken(initial_level_, integrity_level_, IMPERSONATION, |
- lockdown_default_dacl_, initial); |
- if (ERROR_SUCCESS != result) |
- return SBOX_ERROR_GENERIC; |
- |
- return SBOX_ALL_OK; |
-} |
- |
-const AppContainerAttributes* PolicyBase::GetAppContainer() const { |
- if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) |
- return NULL; |
- |
- return appcontainer_list_.get(); |
-} |
- |
-PSID PolicyBase::GetLowBoxSid() const { |
- return lowbox_sid_; |
-} |
- |
-bool PolicyBase::AddTarget(TargetProcess* target) { |
- if (NULL != policy_) |
- policy_maker_->Done(); |
- |
- if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), |
- mitigations_)) { |
- return false; |
- } |
- |
- if (!SetupAllInterceptions(target)) |
- return false; |
- |
- if (!SetupHandleCloser(target)) |
- return false; |
- |
- // Initialize the sandbox infrastructure for the target. |
- if (ERROR_SUCCESS != |
- target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize)) |
- return false; |
- |
- g_shared_delayed_integrity_level = delayed_integrity_level_; |
- ResultCode ret = target->TransferVariable( |
- "g_shared_delayed_integrity_level", |
- &g_shared_delayed_integrity_level, |
- sizeof(g_shared_delayed_integrity_level)); |
- g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; |
- if (SBOX_ALL_OK != ret) |
- return false; |
- |
- // Add in delayed mitigations and pseudo-mitigations enforced at startup. |
- g_shared_delayed_mitigations = delayed_mitigations_ | |
- FilterPostStartupProcessMitigations(mitigations_); |
- if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations)) |
- return false; |
- |
- ret = target->TransferVariable("g_shared_delayed_mitigations", |
- &g_shared_delayed_mitigations, |
- sizeof(g_shared_delayed_mitigations)); |
- g_shared_delayed_mitigations = 0; |
- if (SBOX_ALL_OK != ret) |
- return false; |
- |
- AutoLock lock(&lock_); |
- targets_.push_back(target); |
- return true; |
-} |
- |
-bool PolicyBase::OnJobEmpty(HANDLE job) { |
- AutoLock lock(&lock_); |
- TargetSet::iterator it; |
- for (it = targets_.begin(); it != targets_.end(); ++it) { |
- if ((*it)->Job() == job) |
- break; |
- } |
- if (it == targets_.end()) { |
- return false; |
- } |
- TargetProcess* target = *it; |
- targets_.erase(it); |
- delete target; |
- return true; |
-} |
- |
-void PolicyBase::SetDisconnectCsrss() { |
- if (base::win::GetVersion() >= base::win::VERSION_WIN8) { |
- is_csrss_connected_ = false; |
- AddKernelObjectToClose(L"ALPC Port", NULL); |
- } |
-} |
- |
-EvalResult PolicyBase::EvalPolicy(int service, |
- CountedParameterSetBase* params) { |
- if (NULL != policy_) { |
- if (NULL == policy_->entry[service]) { |
- // There is no policy for this particular service. This is not a big |
- // deal. |
- return DENY_ACCESS; |
- } |
- for (int i = 0; i < params->count; i++) { |
- if (!params->parameters[i].IsValid()) { |
- NOTREACHED(); |
- return SIGNAL_ALARM; |
- } |
- } |
- PolicyProcessor pol_evaluator(policy_->entry[service]); |
- PolicyResult result = pol_evaluator.Evaluate(kShortEval, |
- params->parameters, |
- params->count); |
- if (POLICY_MATCH == result) { |
- return pol_evaluator.GetAction(); |
- } |
- DCHECK(POLICY_ERROR != result); |
- } |
- |
- return DENY_ACCESS; |
-} |
- |
-HANDLE PolicyBase::GetStdoutHandle() { |
- return stdout_handle_; |
-} |
- |
-HANDLE PolicyBase::GetStderrHandle() { |
- return stderr_handle_; |
-} |
- |
-bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { |
- InterceptionManager manager(target, relaxed_interceptions_); |
- |
- if (policy_) { |
- for (int i = 0; i < IPC_LAST_TAG; i++) { |
- if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i)) |
- return false; |
- } |
- } |
- |
- if (!blacklisted_dlls_.empty()) { |
- std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); |
- for (; it != blacklisted_dlls_.end(); ++it) { |
- manager.AddToUnloadModules(it->c_str()); |
- } |
- } |
- |
- if (!SetupBasicInterceptions(&manager, is_csrss_connected_)) |
- return false; |
- |
- if (!manager.InitializeInterceptions()) |
- return false; |
- |
- // Finally, setup imports on the target so the interceptions can work. |
- return SetupNtdllImports(target); |
-} |
- |
-bool PolicyBase::SetupHandleCloser(TargetProcess* target) { |
- return handle_closer_.InitializeTargetHandles(target); |
-} |
- |
-ResultCode PolicyBase::AddRuleInternal(SubSystem subsystem, |
- Semantics semantics, |
- const wchar_t* pattern) { |
- if (NULL == policy_) { |
- policy_ = MakeBrokerPolicyMemory(); |
- DCHECK(policy_); |
- policy_maker_ = new LowLevelPolicy(policy_); |
- DCHECK(policy_maker_); |
- } |
- |
- switch (subsystem) { |
- case SUBSYS_FILES: { |
- if (!file_system_init_) { |
- if (!FileSystemPolicy::SetInitialRules(policy_maker_)) |
- return SBOX_ERROR_BAD_PARAMS; |
- file_system_init_ = true; |
- } |
- if (!FileSystemPolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- case SUBSYS_SYNC: { |
- if (!SyncPolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- case SUBSYS_PROCESS: { |
- if (lockdown_level_ < USER_INTERACTIVE && |
- TargetPolicy::PROCESS_ALL_EXEC == semantics) { |
- // This is unsupported. This is a huge security risk to give full access |
- // to a process handle. |
- return SBOX_ERROR_UNSUPPORTED; |
- } |
- if (!ProcessPolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- case SUBSYS_NAMED_PIPES: { |
- if (!NamedPipePolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- case SUBSYS_REGISTRY: { |
- if (!RegistryPolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- case SUBSYS_HANDLES: { |
- if (!HandlePolicy::GenerateRules(pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- |
- case SUBSYS_WIN32K_LOCKDOWN: { |
- if (!ProcessMitigationsWin32KLockdownPolicy::GenerateRules( |
- pattern, semantics, policy_maker_)) { |
- NOTREACHED(); |
- return SBOX_ERROR_BAD_PARAMS; |
- } |
- break; |
- } |
- |
- default: { return SBOX_ERROR_UNSUPPORTED; } |
- } |
- |
- return SBOX_ALL_OK; |
-} |
- |
-} // namespace sandbox |