1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/job.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,116 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "sandbox/win/src/job.h" 1.9 + 1.10 +#include "base/win/windows_version.h" 1.11 +#include "sandbox/win/src/restricted_token.h" 1.12 + 1.13 +namespace sandbox { 1.14 + 1.15 +Job::~Job() { 1.16 + if (job_handle_) 1.17 + ::CloseHandle(job_handle_); 1.18 +}; 1.19 + 1.20 +DWORD Job::Init(JobLevel security_level, wchar_t *job_name, 1.21 + DWORD ui_exceptions) { 1.22 + if (job_handle_) 1.23 + return ERROR_ALREADY_INITIALIZED; 1.24 + 1.25 + job_handle_ = ::CreateJobObject(NULL, // No security attribute 1.26 + job_name); 1.27 + if (!job_handle_) 1.28 + return ::GetLastError(); 1.29 + 1.30 + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = {0}; 1.31 + JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0}; 1.32 + 1.33 + // Set the settings for the different security levels. Note: The higher levels 1.34 + // inherit from the lower levels. 1.35 + switch (security_level) { 1.36 + case JOB_LOCKDOWN: { 1.37 + jeli.BasicLimitInformation.LimitFlags |= 1.38 + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; 1.39 + } 1.40 + case JOB_RESTRICTED: { 1.41 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD; 1.42 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_READCLIPBOARD; 1.43 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES; 1.44 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS; 1.45 + } 1.46 + case JOB_LIMITED_USER: { 1.47 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS; 1.48 + jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; 1.49 + jeli.BasicLimitInformation.ActiveProcessLimit = 1; 1.50 + } 1.51 + case JOB_INTERACTIVE: { 1.52 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS; 1.53 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP; 1.54 + jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS; 1.55 + } 1.56 + case JOB_UNPROTECTED: { 1.57 + // The JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE flag is not supported on 1.58 + // Windows 2000. We need a mechanism on Windows 2000 to ensure 1.59 + // that processes in the job are terminated when the job is closed 1.60 + if (base::win::GetVersion() == base::win::VERSION_PRE_XP) 1.61 + break; 1.62 + 1.63 + jeli.BasicLimitInformation.LimitFlags |= 1.64 + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; 1.65 + break; 1.66 + } 1.67 + default: { 1.68 + return ERROR_BAD_ARGUMENTS; 1.69 + } 1.70 + } 1.71 + 1.72 + if (FALSE == ::SetInformationJobObject(job_handle_, 1.73 + JobObjectExtendedLimitInformation, 1.74 + &jeli, 1.75 + sizeof(jeli))) { 1.76 + return ::GetLastError(); 1.77 + } 1.78 + 1.79 + jbur.UIRestrictionsClass = jbur.UIRestrictionsClass & (~ui_exceptions); 1.80 + if (FALSE == ::SetInformationJobObject(job_handle_, 1.81 + JobObjectBasicUIRestrictions, 1.82 + &jbur, 1.83 + sizeof(jbur))) { 1.84 + return ::GetLastError(); 1.85 + } 1.86 + 1.87 + return ERROR_SUCCESS; 1.88 +} 1.89 + 1.90 +DWORD Job::UserHandleGrantAccess(HANDLE handle) { 1.91 + if (!job_handle_) 1.92 + return ERROR_NO_DATA; 1.93 + 1.94 + if (!::UserHandleGrantAccess(handle, 1.95 + job_handle_, 1.96 + TRUE)) { // Access allowed. 1.97 + return ::GetLastError(); 1.98 + } 1.99 + 1.100 + return ERROR_SUCCESS; 1.101 +} 1.102 + 1.103 +HANDLE Job::Detach() { 1.104 + HANDLE handle_temp = job_handle_; 1.105 + job_handle_ = NULL; 1.106 + return handle_temp; 1.107 +} 1.108 + 1.109 +DWORD Job::AssignProcessToJob(HANDLE process_handle) { 1.110 + if (!job_handle_) 1.111 + return ERROR_NO_DATA; 1.112 + 1.113 + if (FALSE == ::AssignProcessToJobObject(job_handle_, process_handle)) 1.114 + return ::GetLastError(); 1.115 + 1.116 + return ERROR_SUCCESS; 1.117 +} 1.118 + 1.119 +} // namespace sandbox