summaryrefslogtreecommitdiffstats
path: root/sandbox/src/broker_services.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/src/broker_services.cc')
-rw-r--r--sandbox/src/broker_services.cc56
1 files changed, 53 insertions, 3 deletions
diff --git a/sandbox/src/broker_services.cc b/sandbox/src/broker_services.cc
index f6a0577..0b1fbe0 100644
--- a/sandbox/src/broker_services.cc
+++ b/sandbox/src/broker_services.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// 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/src/broker_services.h"
+#include <AclAPI.h>
+
#include "base/logging.h"
#include "base/threading/platform_thread.h"
#include "sandbox/src/sandbox_policy_base.h"
@@ -42,20 +44,53 @@ enum {
THREAD_CTRL_LAST
};
+// Adds deny ACEs to broker and returns the security descriptor so it can
+// be applied to target processes. The returned descriptor must be freed by
+// calling LocalFree.
+PSECURITY_DESCRIPTOR SetSecurityDescriptorForBroker() {
+ static bool is_initialized = false;
+ DWORD error = ERROR_SUCCESS;
+ PSECURITY_DESCRIPTOR security_descriptor = NULL;
+
+ if (!is_initialized) {
+ error = sandbox::SetObjectDenyRestrictedAndNull(GetCurrentProcess(),
+ SE_KERNEL_OBJECT);
+ if (error) {
+ ::SetLastError(error);
+ return NULL;
+ }
+
+ is_initialized = true;
+ }
+
+ // Save off resulting security descriptor for spawning the targets.
+ error = ::GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL,
+ NULL, NULL, &security_descriptor);
+ if (error) {
+ ::SetLastError(error);
+ return NULL;
+ }
+
+ return security_descriptor;
+}
+
}
namespace sandbox {
BrokerServicesBase::BrokerServicesBase()
: thread_pool_(NULL), job_port_(NULL), no_targets_(NULL),
- job_thread_(NULL) {
+ security_descriptor_(NULL), job_thread_(NULL) {
}
// The broker uses a dedicated worker thread that services the job completion
// port to perform policy notifications and associated cleanup tasks.
ResultCode BrokerServicesBase::Init() {
- if ((NULL != job_port_) || (NULL != thread_pool_))
+ if ((NULL != job_port_) || (NULL != thread_pool_) ||
+ (NULL != security_descriptor_)) {
return SBOX_ERROR_UNEXPECTED_CALL;
+ }
::InitializeCriticalSection(&lock_);
@@ -63,6 +98,10 @@ ResultCode BrokerServicesBase::Init() {
if (NULL == job_port_)
return SBOX_ERROR_GENERIC;
+ security_descriptor_ = SetSecurityDescriptorForBroker();
+ if (NULL == security_descriptor_)
+ return SBOX_ERROR_GENERIC;
+
no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL);
job_thread_ = ::CreateThread(NULL, 0, // Default security and stack.
@@ -104,6 +143,10 @@ BrokerServicesBase::~BrokerServicesBase() {
::CloseHandle(job_thread_);
delete thread_pool_;
::CloseHandle(no_targets_);
+
+ if (security_descriptor_)
+ ::LocalFree(security_descriptor_);
+
// If job_port_ isn't NULL, assumes that the lock has been initialized.
if (job_port_)
::DeleteCriticalSection(&lock_);
@@ -263,13 +306,20 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
// Create the TargetProces object and spawn the target suspended. Note that
// Brokerservices does not own the target object. It is owned by the Policy.
PROCESS_INFORMATION process_info = {0};
+
TargetProcess* target = new TargetProcess(initial_token, lockdown_token,
job, thread_pool_);
std::wstring desktop = policy_base->GetAlternateDesktop();
+ // Set the security descriptor so the target picks up deny ACEs.
+ SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes),
+ security_descriptor_,
+ FALSE};
+
win_result = target->Create(exe_path, command_line,
desktop.empty() ? NULL : desktop.c_str(),
+ &security_attributes,
&process_info);
if (ERROR_SUCCESS != win_result)
return SpawnCleanup(target, win_result);