diff options
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/job.cc')
-rw-r--r-- | security/sandbox/chromium/sandbox/win/src/job.cc | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/job.cc b/security/sandbox/chromium/sandbox/win/src/job.cc new file mode 100644 index 0000000000..39baffb193 --- /dev/null +++ b/security/sandbox/chromium/sandbox/win/src/job.cc @@ -0,0 +1,117 @@ +// Copyright (c) 2011 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/job.h" + +#include <stddef.h> +#include <utility> + +#include "base/win/windows_version.h" +#include "sandbox/win/src/restricted_token.h" + +namespace sandbox { + +Job::Job() : job_handle_(nullptr) {} + +Job::~Job() {} + +DWORD Job::Init(JobLevel security_level, + const wchar_t* job_name, + DWORD ui_exceptions, + size_t memory_limit) { + if (job_handle_.IsValid()) + return ERROR_ALREADY_INITIALIZED; + + job_handle_.Set(::CreateJobObject(nullptr, // No security attribute + job_name)); + if (!job_handle_.IsValid()) + return ::GetLastError(); + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {}; + JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {}; + + // Set the settings for the different security levels. Note: The higher levels + // inherit from the lower levels. + switch (security_level) { + case JOB_LOCKDOWN: { + jeli.BasicLimitInformation.LimitFlags |= + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; + FALLTHROUGH; + } + case JOB_RESTRICTED: { + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD; + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_READCLIPBOARD; + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES; + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS; + FALLTHROUGH; + } + case JOB_LIMITED_USER: { + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS; + jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; + jeli.BasicLimitInformation.ActiveProcessLimit = 1; + FALLTHROUGH; + } + case JOB_INTERACTIVE: { + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS; + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP; + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS; + FALLTHROUGH; + } + case JOB_UNPROTECTED: { + if (memory_limit) { + jeli.BasicLimitInformation.LimitFlags |= + JOB_OBJECT_LIMIT_PROCESS_MEMORY; + jeli.ProcessMemoryLimit = memory_limit; + } + + jeli.BasicLimitInformation.LimitFlags |= + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + break; + } + default: { return ERROR_BAD_ARGUMENTS; } + } + + if (!::SetInformationJobObject(job_handle_.Get(), + JobObjectExtendedLimitInformation, &jeli, + sizeof(jeli))) { + return ::GetLastError(); + } + + jbur.UIRestrictionsClass = jbur.UIRestrictionsClass & (~ui_exceptions); + if (!::SetInformationJobObject(job_handle_.Get(), + JobObjectBasicUIRestrictions, &jbur, + sizeof(jbur))) { + return ::GetLastError(); + } + + return ERROR_SUCCESS; +} + +DWORD Job::UserHandleGrantAccess(HANDLE handle) { + if (!job_handle_.IsValid()) + return ERROR_NO_DATA; + + if (!::UserHandleGrantAccess(handle, job_handle_.Get(), + true)) { // Access allowed. + return ::GetLastError(); + } + + return ERROR_SUCCESS; +} + +base::win::ScopedHandle Job::Take() { + return std::move(job_handle_); +} + +DWORD Job::AssignProcessToJob(HANDLE process_handle) { + if (!job_handle_.IsValid()) + return ERROR_NO_DATA; + + if (!::AssignProcessToJobObject(job_handle_.Get(), process_handle)) + return ::GetLastError(); + + return ERROR_SUCCESS; +} + +} // namespace sandbox |