| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/win/src/sandbox_policy_base.h" | 5 #include "sandbox/win/src/sandbox_policy.h" |
| 6 | 6 |
| 7 #include <sddl.h> | 7 #include <sddl.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/win/windows_version.h" | 15 #include "base/win/windows_version.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // The standard windows size for one memory page. | 39 // The standard windows size for one memory page. |
| 40 const size_t kOneMemPage = 4096; | 40 const size_t kOneMemPage = 4096; |
| 41 // The IPC and Policy shared memory sizes. | 41 // The IPC and Policy shared memory sizes. |
| 42 const size_t kIPCMemSize = kOneMemPage * 2; | 42 const size_t kIPCMemSize = kOneMemPage * 2; |
| 43 const size_t kPolMemSize = kOneMemPage * 14; | 43 const size_t kPolMemSize = kOneMemPage * 14; |
| 44 | 44 |
| 45 // Helper function to allocate space (on the heap) for policy. | 45 // Helper function to allocate space (on the heap) for policy. |
| 46 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() { | 46 sandbox::PolicyGlobal* MakeBrokerPolicyMemory() { |
| 47 const size_t kTotalPolicySz = kPolMemSize; | 47 const size_t kTotalPolicySz = kPolMemSize; |
| 48 sandbox::PolicyGlobal* policy = static_cast<sandbox::PolicyGlobal*> | 48 sandbox::PolicyGlobal* policy = |
| 49 (::operator new(kTotalPolicySz)); | 49 static_cast<sandbox::PolicyGlobal*>(::operator new(kTotalPolicySz)); |
| 50 DCHECK(policy); | 50 DCHECK(policy); |
| 51 memset(policy, 0, kTotalPolicySz); | 51 memset(policy, 0, kTotalPolicySz); |
| 52 policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal); | 52 policy->data_size = kTotalPolicySz - sizeof(sandbox::PolicyGlobal); |
| 53 return policy; | 53 return policy; |
| 54 } | 54 } |
| 55 | 55 |
| 56 bool IsInheritableHandle(HANDLE handle) { | 56 bool IsInheritableHandle(HANDLE handle) { |
| 57 if (!handle) | 57 if (!handle) |
| 58 return false; | 58 return false; |
| 59 if (handle == INVALID_HANDLE_VALUE) | 59 if (handle == INVALID_HANDLE_VALUE) |
| 60 return false; | 60 return false; |
| 61 // File handles (FILE_TYPE_DISK) and pipe handles are known to be | 61 // File handles (FILE_TYPE_DISK) and pipe handles are known to be |
| 62 // inheritable. Console handles (FILE_TYPE_CHAR) are not | 62 // inheritable. Console handles (FILE_TYPE_CHAR) are not |
| 63 // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST. | 63 // inheritable via PROC_THREAD_ATTRIBUTE_HANDLE_LIST. |
| 64 DWORD handle_type = GetFileType(handle); | 64 DWORD handle_type = GetFileType(handle); |
| 65 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; | 65 return handle_type == FILE_TYPE_DISK || handle_type == FILE_TYPE_PIPE; |
| 66 } | 66 } |
| 67 | 67 |
| 68 HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) { | 68 HANDLE CreateLowBoxObjectDirectory(PSID lowbox_sid) { |
| 69 DWORD session_id = 0; | 69 DWORD session_id = 0; |
| 70 if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) | 70 if (!::ProcessIdToSessionId(::GetCurrentProcessId(), &session_id)) |
| 71 return NULL; | 71 return NULL; |
| 72 | 72 |
| 73 LPWSTR sid_string = NULL; | 73 LPWSTR sid_string = NULL; |
| 74 if (!::ConvertSidToStringSid(lowbox_sid, &sid_string)) | 74 if (!::ConvertSidToStringSid(lowbox_sid, &sid_string)) |
| 75 return NULL; | 75 return NULL; |
| 76 | 76 |
| 77 base::string16 directory_path = base::StringPrintf( | 77 base::string16 directory_path = |
| 78 L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls", | 78 base::StringPrintf(L"\\Sessions\\%d\\AppContainerNamedObjects\\%ls", |
| 79 session_id, sid_string).c_str(); | 79 session_id, sid_string) |
| 80 .c_str(); |
| 80 ::LocalFree(sid_string); | 81 ::LocalFree(sid_string); |
| 81 | 82 |
| 82 NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL; | 83 NtCreateDirectoryObjectFunction CreateObjectDirectory = NULL; |
| 83 ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory); | 84 ResolveNTFunctionPtr("NtCreateDirectoryObject", &CreateObjectDirectory); |
| 84 | 85 |
| 85 OBJECT_ATTRIBUTES obj_attr; | 86 OBJECT_ATTRIBUTES obj_attr; |
| 86 UNICODE_STRING obj_name; | 87 UNICODE_STRING obj_name; |
| 87 sandbox::InitObjectAttribs(directory_path, | 88 sandbox::InitObjectAttribs(directory_path, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, |
| 88 OBJ_CASE_INSENSITIVE | OBJ_OPENIF, | 89 NULL, &obj_attr, &obj_name, NULL); |
| 89 NULL, | |
| 90 &obj_attr, | |
| 91 &obj_name, | |
| 92 NULL); | |
| 93 | 90 |
| 94 HANDLE handle = NULL; | 91 HANDLE handle = NULL; |
| 95 NTSTATUS status = CreateObjectDirectory(&handle, | 92 NTSTATUS status = |
| 96 DIRECTORY_ALL_ACCESS, | 93 CreateObjectDirectory(&handle, DIRECTORY_ALL_ACCESS, &obj_attr); |
| 97 &obj_attr); | |
| 98 | 94 |
| 99 if (!NT_SUCCESS(status)) | 95 if (!NT_SUCCESS(status)) |
| 100 return NULL; | 96 return NULL; |
| 101 | 97 |
| 102 return handle; | 98 return handle; |
| 103 } | 99 } |
| 104 | 100 |
| 105 } // namespace | 101 } // namespace |
| 106 | 102 |
| 107 namespace sandbox { | 103 namespace sandbox { |
| 108 | 104 |
| 109 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; | 105 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level; |
| 110 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; | 106 SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; |
| 111 | 107 |
| 112 // Initializes static members. | 108 // Initializes static members. |
| 113 HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; | 109 HWINSTA TargetPolicy::alternate_winstation_handle_ = NULL; |
| 114 HDESK PolicyBase::alternate_desktop_handle_ = NULL; | 110 HDESK TargetPolicy::alternate_desktop_handle_ = NULL; |
| 115 IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = | 111 IntegrityLevel TargetPolicy::alternate_desktop_integrity_level_label_ = |
| 116 INTEGRITY_LEVEL_SYSTEM; | 112 INTEGRITY_LEVEL_SYSTEM; |
| 117 | 113 |
| 118 PolicyBase::PolicyBase() | 114 TargetPolicy::TargetPolicy() |
| 119 : ref_count(1), | 115 : ref_count(1), |
| 120 lockdown_level_(USER_LOCKDOWN), | 116 lockdown_level_(USER_LOCKDOWN), |
| 121 initial_level_(USER_LOCKDOWN), | 117 initial_level_(USER_LOCKDOWN), |
| 122 job_level_(JOB_LOCKDOWN), | 118 job_level_(JOB_LOCKDOWN), |
| 123 ui_exceptions_(0), | 119 ui_exceptions_(0), |
| 124 memory_limit_(0), | 120 memory_limit_(0), |
| 125 use_alternate_desktop_(false), | 121 use_alternate_desktop_(false), |
| 126 use_alternate_winstation_(false), | 122 use_alternate_winstation_(false), |
| 127 file_system_init_(false), | 123 file_system_init_(false), |
| 128 relaxed_interceptions_(true), | 124 relaxed_interceptions_(true), |
| 129 stdout_handle_(INVALID_HANDLE_VALUE), | 125 stdout_handle_(INVALID_HANDLE_VALUE), |
| 130 stderr_handle_(INVALID_HANDLE_VALUE), | 126 stderr_handle_(INVALID_HANDLE_VALUE), |
| 131 integrity_level_(INTEGRITY_LEVEL_LAST), | 127 integrity_level_(INTEGRITY_LEVEL_LAST), |
| 132 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), | 128 delayed_integrity_level_(INTEGRITY_LEVEL_LAST), |
| 133 mitigations_(0), | 129 mitigations_(0), |
| 134 delayed_mitigations_(0), | 130 delayed_mitigations_(0), |
| 135 policy_maker_(NULL), | 131 policy_maker_(NULL), |
| 136 policy_(NULL), | 132 policy_(NULL), |
| 137 lowbox_sid_(NULL) { | 133 lowbox_sid_(NULL) { |
| 138 ::InitializeCriticalSection(&lock_); | 134 ::InitializeCriticalSection(&lock_); |
| 139 dispatcher_.reset(new TopLevelDispatcher(this)); | 135 dispatcher_.reset(new TopLevelDispatcher(this)); |
| 140 } | 136 } |
| 141 | 137 |
| 142 PolicyBase::~PolicyBase() { | 138 TargetPolicy::~TargetPolicy() { |
| 143 ClearSharedHandles(); | 139 ClearSharedHandles(); |
| 144 | 140 |
| 145 TargetSet::iterator it; | 141 TargetSet::iterator it; |
| 146 for (it = targets_.begin(); it != targets_.end(); ++it) { | 142 for (it = targets_.begin(); it != targets_.end(); ++it) { |
| 147 TargetProcess* target = (*it); | 143 TargetProcess* target = (*it); |
| 148 delete target; | 144 delete target; |
| 149 } | 145 } |
| 150 delete policy_maker_; | 146 delete policy_maker_; |
| 151 delete policy_; | 147 delete policy_; |
| 152 | 148 |
| 153 if (lowbox_sid_) | 149 if (lowbox_sid_) |
| 154 ::LocalFree(lowbox_sid_); | 150 ::LocalFree(lowbox_sid_); |
| 155 | 151 |
| 156 ::DeleteCriticalSection(&lock_); | 152 ::DeleteCriticalSection(&lock_); |
| 157 } | 153 } |
| 158 | 154 |
| 159 void PolicyBase::AddRef() { | 155 void TargetPolicy::AddRef() { |
| 160 ::InterlockedIncrement(&ref_count); | 156 ::InterlockedIncrement(&ref_count); |
| 161 } | 157 } |
| 162 | 158 |
| 163 void PolicyBase::Release() { | 159 void TargetPolicy::Release() { |
| 164 if (0 == ::InterlockedDecrement(&ref_count)) | 160 if (0 == ::InterlockedDecrement(&ref_count)) |
| 165 delete this; | 161 delete this; |
| 166 } | 162 } |
| 167 | 163 |
| 168 ResultCode PolicyBase::SetTokenLevel(TokenLevel initial, TokenLevel lockdown) { | 164 ResultCode TargetPolicy::SetTokenLevel(TokenLevel initial, |
| 165 TokenLevel lockdown) { |
| 169 if (initial < lockdown) { | 166 if (initial < lockdown) { |
| 170 return SBOX_ERROR_BAD_PARAMS; | 167 return SBOX_ERROR_BAD_PARAMS; |
| 171 } | 168 } |
| 172 initial_level_ = initial; | 169 initial_level_ = initial; |
| 173 lockdown_level_ = lockdown; | 170 lockdown_level_ = lockdown; |
| 174 return SBOX_ALL_OK; | 171 return SBOX_ALL_OK; |
| 175 } | 172 } |
| 176 | 173 |
| 177 TokenLevel PolicyBase::GetInitialTokenLevel() const { | 174 TokenLevel TargetPolicy::GetInitialTokenLevel() const { |
| 178 return initial_level_; | 175 return initial_level_; |
| 179 } | 176 } |
| 180 | 177 |
| 181 TokenLevel PolicyBase::GetLockdownTokenLevel() const{ | 178 TokenLevel TargetPolicy::GetLockdownTokenLevel() const { |
| 182 return lockdown_level_; | 179 return lockdown_level_; |
| 183 } | 180 } |
| 184 | 181 |
| 185 ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) { | 182 ResultCode TargetPolicy::SetJobLevel(JobLevel job_level, uint32 ui_exceptions) { |
| 186 if (memory_limit_ && job_level == JOB_NONE) { | 183 if (memory_limit_ && job_level == JOB_NONE) { |
| 187 return SBOX_ERROR_BAD_PARAMS; | 184 return SBOX_ERROR_BAD_PARAMS; |
| 188 } | 185 } |
| 189 job_level_ = job_level; | 186 job_level_ = job_level; |
| 190 ui_exceptions_ = ui_exceptions; | 187 ui_exceptions_ = ui_exceptions; |
| 191 return SBOX_ALL_OK; | 188 return SBOX_ALL_OK; |
| 192 } | 189 } |
| 193 | 190 |
| 194 ResultCode PolicyBase::SetJobMemoryLimit(size_t memory_limit) { | 191 ResultCode TargetPolicy::SetJobMemoryLimit(size_t memory_limit) { |
| 195 if (memory_limit && job_level_ == JOB_NONE) { | 192 if (memory_limit && job_level_ == JOB_NONE) { |
| 196 return SBOX_ERROR_BAD_PARAMS; | 193 return SBOX_ERROR_BAD_PARAMS; |
| 197 } | 194 } |
| 198 memory_limit_ = memory_limit; | 195 memory_limit_ = memory_limit; |
| 199 return SBOX_ALL_OK; | 196 return SBOX_ALL_OK; |
| 200 } | 197 } |
| 201 | 198 |
| 202 ResultCode PolicyBase::SetAlternateDesktop(bool alternate_winstation) { | 199 ResultCode TargetPolicy::SetAlternateDesktop(bool alternate_winstation) { |
| 203 use_alternate_desktop_ = true; | 200 use_alternate_desktop_ = true; |
| 204 use_alternate_winstation_ = alternate_winstation; | 201 use_alternate_winstation_ = alternate_winstation; |
| 205 return CreateAlternateDesktop(alternate_winstation); | 202 return CreateAlternateDesktop(alternate_winstation); |
| 206 } | 203 } |
| 207 | 204 |
| 208 base::string16 PolicyBase::GetAlternateDesktop() const { | 205 base::string16 TargetPolicy::GetAlternateDesktop() const { |
| 209 // No alternate desktop or winstation. Return an empty string. | 206 // No alternate desktop or winstation. Return an empty string. |
| 210 if (!use_alternate_desktop_ && !use_alternate_winstation_) { | 207 if (!use_alternate_desktop_ && !use_alternate_winstation_) { |
| 211 return base::string16(); | 208 return base::string16(); |
| 212 } | 209 } |
| 213 | 210 |
| 214 // The desktop and winstation should have been created by now. | 211 // The desktop and winstation should have been created by now. |
| 215 // If we hit this scenario, it means that the user ignored the failure | 212 // If we hit this scenario, it means that the user ignored the failure |
| 216 // during SetAlternateDesktop, so we ignore it here too. | 213 // during SetAlternateDesktop, so we ignore it here too. |
| 217 if (use_alternate_desktop_ && !alternate_desktop_handle_) { | 214 if (use_alternate_desktop_ && !alternate_desktop_handle_) { |
| 218 return base::string16(); | 215 return base::string16(); |
| 219 } | 216 } |
| 220 if (use_alternate_winstation_ && (!alternate_desktop_handle_ || | 217 if (use_alternate_winstation_ && |
| 221 !alternate_winstation_handle_)) { | 218 (!alternate_desktop_handle_ || !alternate_winstation_handle_)) { |
| 222 return base::string16(); | 219 return base::string16(); |
| 223 } | 220 } |
| 224 | 221 |
| 225 return GetFullDesktopName(alternate_winstation_handle_, | 222 return GetFullDesktopName(alternate_winstation_handle_, |
| 226 alternate_desktop_handle_); | 223 alternate_desktop_handle_); |
| 227 } | 224 } |
| 228 | 225 |
| 229 ResultCode PolicyBase::CreateAlternateDesktop(bool alternate_winstation) { | 226 ResultCode TargetPolicy::CreateAlternateDesktop(bool alternate_winstation) { |
| 230 if (alternate_winstation) { | 227 if (alternate_winstation) { |
| 231 // Previously called with alternate_winstation = false? | 228 // Previously called with alternate_winstation = false? |
| 232 if (!alternate_winstation_handle_ && alternate_desktop_handle_) | 229 if (!alternate_winstation_handle_ && alternate_desktop_handle_) |
| 233 return SBOX_ERROR_UNSUPPORTED; | 230 return SBOX_ERROR_UNSUPPORTED; |
| 234 | 231 |
| 235 // Check if it's already created. | 232 // Check if it's already created. |
| 236 if (alternate_winstation_handle_ && alternate_desktop_handle_) | 233 if (alternate_winstation_handle_ && alternate_desktop_handle_) |
| 237 return SBOX_ALL_OK; | 234 return SBOX_ALL_OK; |
| 238 | 235 |
| 239 DCHECK(!alternate_winstation_handle_); | 236 DCHECK(!alternate_winstation_handle_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 270 |
| 274 // Verify that everything is fine. | 271 // Verify that everything is fine. |
| 275 if (!alternate_desktop_handle_ || | 272 if (!alternate_desktop_handle_ || |
| 276 GetWindowObjectName(alternate_desktop_handle_).empty()) | 273 GetWindowObjectName(alternate_desktop_handle_).empty()) |
| 277 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; | 274 return SBOX_ERROR_CANNOT_CREATE_DESKTOP; |
| 278 } | 275 } |
| 279 | 276 |
| 280 return SBOX_ALL_OK; | 277 return SBOX_ALL_OK; |
| 281 } | 278 } |
| 282 | 279 |
| 283 void PolicyBase::DestroyAlternateDesktop() { | 280 void TargetPolicy::DestroyAlternateDesktop() { |
| 284 if (alternate_desktop_handle_) { | 281 if (alternate_desktop_handle_) { |
| 285 ::CloseDesktop(alternate_desktop_handle_); | 282 ::CloseDesktop(alternate_desktop_handle_); |
| 286 alternate_desktop_handle_ = NULL; | 283 alternate_desktop_handle_ = NULL; |
| 287 } | 284 } |
| 288 | 285 |
| 289 if (alternate_winstation_handle_) { | 286 if (alternate_winstation_handle_) { |
| 290 ::CloseWindowStation(alternate_winstation_handle_); | 287 ::CloseWindowStation(alternate_winstation_handle_); |
| 291 alternate_winstation_handle_ = NULL; | 288 alternate_winstation_handle_ = NULL; |
| 292 } | 289 } |
| 293 } | 290 } |
| 294 | 291 |
| 295 ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) { | 292 ResultCode TargetPolicy::SetIntegrityLevel(IntegrityLevel integrity_level) { |
| 296 integrity_level_ = integrity_level; | 293 integrity_level_ = integrity_level; |
| 297 return SBOX_ALL_OK; | 294 return SBOX_ALL_OK; |
| 298 } | 295 } |
| 299 | 296 |
| 300 IntegrityLevel PolicyBase::GetIntegrityLevel() const { | 297 IntegrityLevel TargetPolicy::GetIntegrityLevel() const { |
| 301 return integrity_level_; | 298 return integrity_level_; |
| 302 } | 299 } |
| 303 | 300 |
| 304 ResultCode PolicyBase::SetDelayedIntegrityLevel( | 301 ResultCode TargetPolicy::SetDelayedIntegrityLevel( |
| 305 IntegrityLevel integrity_level) { | 302 IntegrityLevel integrity_level) { |
| 306 delayed_integrity_level_ = integrity_level; | 303 delayed_integrity_level_ = integrity_level; |
| 307 return SBOX_ALL_OK; | 304 return SBOX_ALL_OK; |
| 308 } | 305 } |
| 309 | 306 |
| 310 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { | 307 ResultCode TargetPolicy::SetAppContainer(const wchar_t* sid) { |
| 311 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) | 308 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) |
| 312 return SBOX_ALL_OK; | 309 return SBOX_ALL_OK; |
| 313 | 310 |
| 314 // SetLowBox and SetAppContainer are mutually exclusive. | 311 // SetLowBox and SetAppContainer are mutually exclusive. |
| 315 if (lowbox_sid_) | 312 if (lowbox_sid_) |
| 316 return SBOX_ERROR_UNSUPPORTED; | 313 return SBOX_ERROR_UNSUPPORTED; |
| 317 | 314 |
| 318 // Windows refuses to work with an impersonation token for a process inside | 315 // Windows refuses to work with an impersonation token for a process inside |
| 319 // an AppContainer. If the caller wants to use a more privileged initial | 316 // an AppContainer. If the caller wants to use a more privileged initial |
| 320 // token, or if the lockdown level will prevent the process from starting, | 317 // token, or if the lockdown level will prevent the process from starting, |
| 321 // we have to fail the operation. | 318 // we have to fail the operation. |
| 322 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) | 319 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) |
| 323 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; | 320 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; |
| 324 | 321 |
| 325 DCHECK(!appcontainer_list_.get()); | 322 DCHECK(!appcontainer_list_.get()); |
| 326 appcontainer_list_.reset(new AppContainerAttributes); | 323 appcontainer_list_.reset(new AppContainerAttributes); |
| 327 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); | 324 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); |
| 328 if (rv != SBOX_ALL_OK) | 325 if (rv != SBOX_ALL_OK) |
| 329 return rv; | 326 return rv; |
| 330 | 327 |
| 331 return SBOX_ALL_OK; | 328 return SBOX_ALL_OK; |
| 332 } | 329 } |
| 333 | 330 |
| 334 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { | 331 ResultCode TargetPolicy::SetCapability(const wchar_t* sid) { |
| 335 capabilities_.push_back(sid); | 332 capabilities_.push_back(sid); |
| 336 return SBOX_ALL_OK; | 333 return SBOX_ALL_OK; |
| 337 } | 334 } |
| 338 | 335 |
| 339 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { | 336 ResultCode TargetPolicy::SetLowBox(const wchar_t* sid) { |
| 340 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) | 337 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) |
| 341 return SBOX_ERROR_UNSUPPORTED; | 338 return SBOX_ERROR_UNSUPPORTED; |
| 342 | 339 |
| 343 // SetLowBox and SetAppContainer are mutually exclusive. | 340 // SetLowBox and SetAppContainer are mutually exclusive. |
| 344 if (appcontainer_list_.get()) | 341 if (appcontainer_list_.get()) |
| 345 return SBOX_ERROR_UNSUPPORTED; | 342 return SBOX_ERROR_UNSUPPORTED; |
| 346 | 343 |
| 347 DCHECK(sid); | 344 DCHECK(sid); |
| 348 | 345 |
| 349 if (lowbox_sid_) | 346 if (lowbox_sid_) |
| 350 return SBOX_ERROR_BAD_PARAMS; | 347 return SBOX_ERROR_BAD_PARAMS; |
| 351 | 348 |
| 352 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) | 349 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) |
| 353 return SBOX_ERROR_GENERIC; | 350 return SBOX_ERROR_GENERIC; |
| 354 | 351 |
| 355 return SBOX_ALL_OK; | 352 return SBOX_ALL_OK; |
| 356 } | 353 } |
| 357 | 354 |
| 358 ResultCode PolicyBase::SetProcessMitigations( | 355 ResultCode TargetPolicy::SetProcessMitigations(MitigationFlags flags) { |
| 359 MitigationFlags flags) { | |
| 360 if (!CanSetProcessMitigationsPreStartup(flags)) | 356 if (!CanSetProcessMitigationsPreStartup(flags)) |
| 361 return SBOX_ERROR_BAD_PARAMS; | 357 return SBOX_ERROR_BAD_PARAMS; |
| 362 mitigations_ = flags; | 358 mitigations_ = flags; |
| 363 return SBOX_ALL_OK; | 359 return SBOX_ALL_OK; |
| 364 } | 360 } |
| 365 | 361 |
| 366 MitigationFlags PolicyBase::GetProcessMitigations() { | 362 MitigationFlags TargetPolicy::GetProcessMitigations() { |
| 367 return mitigations_; | 363 return mitigations_; |
| 368 } | 364 } |
| 369 | 365 |
| 370 ResultCode PolicyBase::SetDelayedProcessMitigations( | 366 ResultCode TargetPolicy::SetDelayedProcessMitigations(MitigationFlags flags) { |
| 371 MitigationFlags flags) { | |
| 372 if (!CanSetProcessMitigationsPostStartup(flags)) | 367 if (!CanSetProcessMitigationsPostStartup(flags)) |
| 373 return SBOX_ERROR_BAD_PARAMS; | 368 return SBOX_ERROR_BAD_PARAMS; |
| 374 delayed_mitigations_ = flags; | 369 delayed_mitigations_ = flags; |
| 375 return SBOX_ALL_OK; | 370 return SBOX_ALL_OK; |
| 376 } | 371 } |
| 377 | 372 |
| 378 MitigationFlags PolicyBase::GetDelayedProcessMitigations() const { | 373 MitigationFlags TargetPolicy::GetDelayedProcessMitigations() const { |
| 379 return delayed_mitigations_; | 374 return delayed_mitigations_; |
| 380 } | 375 } |
| 381 | 376 |
| 382 void PolicyBase::SetStrictInterceptions() { | 377 void TargetPolicy::SetStrictInterceptions() { |
| 383 relaxed_interceptions_ = false; | 378 relaxed_interceptions_ = false; |
| 384 } | 379 } |
| 385 | 380 |
| 386 ResultCode PolicyBase::SetStdoutHandle(HANDLE handle) { | 381 ResultCode TargetPolicy::SetStdoutHandle(HANDLE handle) { |
| 387 if (!IsInheritableHandle(handle)) | 382 if (!IsInheritableHandle(handle)) |
| 388 return SBOX_ERROR_BAD_PARAMS; | 383 return SBOX_ERROR_BAD_PARAMS; |
| 389 stdout_handle_ = handle; | 384 stdout_handle_ = handle; |
| 390 return SBOX_ALL_OK; | 385 return SBOX_ALL_OK; |
| 391 } | 386 } |
| 392 | 387 |
| 393 ResultCode PolicyBase::SetStderrHandle(HANDLE handle) { | 388 ResultCode TargetPolicy::SetStderrHandle(HANDLE handle) { |
| 394 if (!IsInheritableHandle(handle)) | 389 if (!IsInheritableHandle(handle)) |
| 395 return SBOX_ERROR_BAD_PARAMS; | 390 return SBOX_ERROR_BAD_PARAMS; |
| 396 stderr_handle_ = handle; | 391 stderr_handle_ = handle; |
| 397 return SBOX_ALL_OK; | 392 return SBOX_ALL_OK; |
| 398 } | 393 } |
| 399 | 394 |
| 400 ResultCode PolicyBase::AddRule(SubSystem subsystem, | 395 ResultCode TargetPolicy::AddRule(SubSystem subsystem, |
| 401 Semantics semantics, | 396 Semantics semantics, |
| 402 const wchar_t* pattern) { | 397 const wchar_t* pattern) { |
| 403 ResultCode result = AddRuleInternal(subsystem, semantics, pattern); | 398 ResultCode result = AddRuleInternal(subsystem, semantics, pattern); |
| 404 LOG_IF(ERROR, result != SBOX_ALL_OK) << "Failed to add sandbox rule." | 399 LOG_IF(ERROR, result != SBOX_ALL_OK) |
| 405 << " error = " << result | 400 << "Failed to add sandbox rule." |
| 406 << ", subsystem = " << subsystem | 401 << " error = " << result << ", subsystem = " << subsystem |
| 407 << ", semantics = " << semantics | 402 << ", semantics = " << semantics << ", pattern = '" << pattern << "'"; |
| 408 << ", pattern = '" << pattern << "'"; | |
| 409 return result; | 403 return result; |
| 410 } | 404 } |
| 411 | 405 |
| 412 ResultCode PolicyBase::AddDllToUnload(const wchar_t* dll_name) { | 406 ResultCode TargetPolicy::AddDllToUnload(const wchar_t* dll_name) { |
| 413 blacklisted_dlls_.push_back(dll_name); | 407 blacklisted_dlls_.push_back(dll_name); |
| 414 return SBOX_ALL_OK; | 408 return SBOX_ALL_OK; |
| 415 } | 409 } |
| 416 | 410 |
| 417 ResultCode PolicyBase::AddKernelObjectToClose(const base::char16* handle_type, | 411 ResultCode TargetPolicy::AddKernelObjectToClose( |
| 418 const base::char16* handle_name) { | 412 const base::char16* handle_type, |
| 413 const base::char16* handle_name) { |
| 419 return handle_closer_.AddHandle(handle_type, handle_name); | 414 return handle_closer_.AddHandle(handle_type, handle_name); |
| 420 } | 415 } |
| 421 | 416 |
| 422 void* PolicyBase::AddHandleToShare(HANDLE handle) { | 417 void* TargetPolicy::AddHandleToShare(HANDLE handle) { |
| 423 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 418 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 424 return nullptr; | 419 return nullptr; |
| 425 | 420 |
| 426 if (!handle) | 421 if (!handle) |
| 427 return nullptr; | 422 return nullptr; |
| 428 | 423 |
| 429 HANDLE duped_handle = nullptr; | 424 HANDLE duped_handle = nullptr; |
| 430 if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), | 425 if (!::DuplicateHandle(::GetCurrentProcess(), handle, ::GetCurrentProcess(), |
| 431 &duped_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { | 426 &duped_handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
| 432 return nullptr; | 427 return nullptr; |
| 433 } | 428 } |
| 434 handles_to_share_.push_back(new base::win::ScopedHandle(duped_handle)); | 429 handles_to_share_.push_back(new base::win::ScopedHandle(duped_handle)); |
| 435 return duped_handle; | 430 return duped_handle; |
| 436 } | 431 } |
| 437 | 432 |
| 438 const HandleList& PolicyBase::GetHandlesBeingShared() { | 433 const HandleList& TargetPolicy::GetHandlesBeingShared() { |
| 439 return handles_to_share_; | 434 return handles_to_share_; |
| 440 } | 435 } |
| 441 | 436 |
| 442 void PolicyBase::ClearSharedHandles() { | 437 void TargetPolicy::ClearSharedHandles() { |
| 443 STLDeleteElements(&handles_to_share_); | 438 STLDeleteElements(&handles_to_share_); |
| 444 } | 439 } |
| 445 | 440 |
| 446 ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { | 441 ResultCode TargetPolicy::MakeJobObject(base::win::ScopedHandle* job) { |
| 447 if (job_level_ != JOB_NONE) { | 442 if (job_level_ != JOB_NONE) { |
| 448 // Create the windows job object. | 443 // Create the windows job object. |
| 449 Job job_obj; | 444 Job job_obj; |
| 450 DWORD result = job_obj.Init(job_level_, NULL, ui_exceptions_, | 445 DWORD result = |
| 451 memory_limit_); | 446 job_obj.Init(job_level_, NULL, ui_exceptions_, memory_limit_); |
| 452 if (ERROR_SUCCESS != result) | 447 if (ERROR_SUCCESS != result) |
| 453 return SBOX_ERROR_GENERIC; | 448 return SBOX_ERROR_GENERIC; |
| 454 | 449 |
| 455 *job = job_obj.Take(); | 450 *job = job_obj.Take(); |
| 456 } else { | 451 } else { |
| 457 *job = base::win::ScopedHandle(); | 452 *job = base::win::ScopedHandle(); |
| 458 } | 453 } |
| 459 return SBOX_ALL_OK; | 454 return SBOX_ALL_OK; |
| 460 } | 455 } |
| 461 | 456 |
| 462 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, | 457 ResultCode TargetPolicy::MakeTokens(base::win::ScopedHandle* initial, |
| 463 base::win::ScopedHandle* lockdown, | 458 base::win::ScopedHandle* lockdown, |
| 464 base::win::ScopedHandle* lowbox) { | 459 base::win::ScopedHandle* lowbox) { |
| 465 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && | 460 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && |
| 466 lowbox_sid_) { | 461 lowbox_sid_) { |
| 467 return SBOX_ERROR_BAD_PARAMS; | 462 return SBOX_ERROR_BAD_PARAMS; |
| 468 } | 463 } |
| 469 | 464 |
| 470 // Create the 'naked' token. This will be the permanent token associated | 465 // Create the 'naked' token. This will be the permanent token associated |
| 471 // with the process and therefore with any thread that is not impersonating. | 466 // with the process and therefore with any thread that is not impersonating. |
| 472 DWORD result = CreateRestrictedToken(lockdown_level_, integrity_level_, | 467 DWORD result = CreateRestrictedToken(lockdown_level_, integrity_level_, |
| 473 PRIMARY, lockdown); | 468 PRIMARY, lockdown); |
| 474 if (ERROR_SUCCESS != result) | 469 if (ERROR_SUCCESS != result) |
| 475 return SBOX_ERROR_GENERIC; | 470 return SBOX_ERROR_GENERIC; |
| 476 | 471 |
| 477 // If we're launching on the alternate desktop we need to make sure the | 472 // If we're launching on the alternate desktop we need to make sure the |
| 478 // integrity label on the object is no higher than the sandboxed process's | 473 // integrity label on the object is no higher than the sandboxed process's |
| 479 // integrity level. So, we lower the label on the desktop process if it's | 474 // integrity level. So, we lower the label on the desktop process if it's |
| 480 // not already low enough for our process. | 475 // not already low enough for our process. |
| 481 if (alternate_desktop_handle_ && use_alternate_desktop_ && | 476 if (alternate_desktop_handle_ && use_alternate_desktop_ && |
| 482 integrity_level_ != INTEGRITY_LEVEL_LAST && | 477 integrity_level_ != INTEGRITY_LEVEL_LAST && |
| 483 alternate_desktop_integrity_level_label_ < integrity_level_ && | 478 alternate_desktop_integrity_level_label_ < integrity_level_ && |
| 484 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { | 479 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { |
| 485 // Integrity label enum is reversed (higher level is a lower value). | 480 // Integrity label enum is reversed (higher level is a lower value). |
| 486 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, | 481 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
| 487 "Integrity level ordering reversed."); | 482 "Integrity level ordering reversed."); |
| 488 result = SetObjectIntegrityLabel(alternate_desktop_handle_, | 483 result = |
| 489 SE_WINDOW_OBJECT, | 484 SetObjectIntegrityLabel(alternate_desktop_handle_, SE_WINDOW_OBJECT, |
| 490 L"", | 485 L"", GetIntegrityLevelString(integrity_level_)); |
| 491 GetIntegrityLevelString(integrity_level_)); | |
| 492 if (ERROR_SUCCESS != result) | 486 if (ERROR_SUCCESS != result) |
| 493 return SBOX_ERROR_GENERIC; | 487 return SBOX_ERROR_GENERIC; |
| 494 | 488 |
| 495 alternate_desktop_integrity_level_label_ = integrity_level_; | 489 alternate_desktop_integrity_level_label_ = integrity_level_; |
| 496 } | 490 } |
| 497 | 491 |
| 498 // We are maintaining two mutually exclusive approaches. One is to start an | 492 // We are maintaining two mutually exclusive approaches. One is to start an |
| 499 // AppContainer process through StartupInfoEx and other is replacing | 493 // AppContainer process through StartupInfoEx and other is replacing |
| 500 // existing token with LowBox token after process creation. | 494 // existing token with LowBox token after process creation. |
| 501 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { | 495 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 517 | 511 |
| 518 if (!lowbox_directory_.IsValid()) | 512 if (!lowbox_directory_.IsValid()) |
| 519 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); | 513 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); |
| 520 DCHECK(lowbox_directory_.IsValid()); | 514 DCHECK(lowbox_directory_.IsValid()); |
| 521 | 515 |
| 522 // The order of handles isn't important in the CreateLowBoxToken call. | 516 // The order of handles isn't important in the CreateLowBoxToken call. |
| 523 // The kernel will maintain a reference to the object directory handle. | 517 // The kernel will maintain a reference to the object directory handle. |
| 524 HANDLE saved_handles[1] = {lowbox_directory_.Get()}; | 518 HANDLE saved_handles[1] = {lowbox_directory_.Get()}; |
| 525 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; | 519 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; |
| 526 | 520 |
| 527 NTSTATUS status = CreateLowBoxToken(&token_lowbox, lockdown->Get(), | 521 NTSTATUS status = CreateLowBoxToken( |
| 528 TOKEN_ALL_ACCESS, &obj_attr, | 522 &token_lowbox, lockdown->Get(), TOKEN_ALL_ACCESS, &obj_attr, |
| 529 lowbox_sid_, 0, NULL, | 523 lowbox_sid_, 0, NULL, saved_handles_count, saved_handles); |
| 530 saved_handles_count, saved_handles); | |
| 531 if (!NT_SUCCESS(status)) | 524 if (!NT_SUCCESS(status)) |
| 532 return SBOX_ERROR_GENERIC; | 525 return SBOX_ERROR_GENERIC; |
| 533 | 526 |
| 534 DCHECK(token_lowbox); | 527 DCHECK(token_lowbox); |
| 535 lowbox->Set(token_lowbox); | 528 lowbox->Set(token_lowbox); |
| 536 } | 529 } |
| 537 | 530 |
| 538 // Create the 'better' token. We use this token as the one that the main | 531 // Create the 'better' token. We use this token as the one that the main |
| 539 // thread uses when booting up the process. It should contain most of | 532 // thread uses when booting up the process. It should contain most of |
| 540 // what we need (before reaching main( )) | 533 // what we need (before reaching main( )) |
| 541 result = CreateRestrictedToken(initial_level_, integrity_level_, | 534 result = CreateRestrictedToken(initial_level_, integrity_level_, |
| 542 IMPERSONATION, initial); | 535 IMPERSONATION, initial); |
| 543 if (ERROR_SUCCESS != result) | 536 if (ERROR_SUCCESS != result) |
| 544 return SBOX_ERROR_GENERIC; | 537 return SBOX_ERROR_GENERIC; |
| 545 | 538 |
| 546 return SBOX_ALL_OK; | 539 return SBOX_ALL_OK; |
| 547 } | 540 } |
| 548 | 541 |
| 549 const AppContainerAttributes* PolicyBase::GetAppContainer() const { | 542 const AppContainerAttributes* TargetPolicy::GetAppContainer() const { |
| 550 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) | 543 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) |
| 551 return NULL; | 544 return NULL; |
| 552 | 545 |
| 553 return appcontainer_list_.get(); | 546 return appcontainer_list_.get(); |
| 554 } | 547 } |
| 555 | 548 |
| 556 PSID PolicyBase::GetLowBoxSid() const { | 549 PSID TargetPolicy::GetLowBoxSid() const { |
| 557 return lowbox_sid_; | 550 return lowbox_sid_; |
| 558 } | 551 } |
| 559 | 552 |
| 560 bool PolicyBase::AddTarget(TargetProcess* target) { | 553 bool TargetPolicy::AddTarget(TargetProcess* target) { |
| 561 if (NULL != policy_) | 554 if (NULL != policy_) |
| 562 policy_maker_->Done(); | 555 policy_maker_->Done(); |
| 563 | 556 |
| 564 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), | 557 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), |
| 565 mitigations_)) { | 558 mitigations_)) { |
| 566 return false; | 559 return false; |
| 567 } | 560 } |
| 568 | 561 |
| 569 if (!SetupAllInterceptions(target)) | 562 if (!SetupAllInterceptions(target)) |
| 570 return false; | 563 return false; |
| 571 | 564 |
| 572 if (!SetupHandleCloser(target)) | 565 if (!SetupHandleCloser(target)) |
| 573 return false; | 566 return false; |
| 574 | 567 |
| 575 // Initialize the sandbox infrastructure for the target. | 568 // Initialize the sandbox infrastructure for the target. |
| 576 if (ERROR_SUCCESS != | 569 if (ERROR_SUCCESS != |
| 577 target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize)) | 570 target->Init(dispatcher_.get(), policy_, kIPCMemSize, kPolMemSize)) |
| 578 return false; | 571 return false; |
| 579 | 572 |
| 580 g_shared_delayed_integrity_level = delayed_integrity_level_; | 573 g_shared_delayed_integrity_level = delayed_integrity_level_; |
| 581 ResultCode ret = target->TransferVariable( | 574 ResultCode ret = target->TransferVariable( |
| 582 "g_shared_delayed_integrity_level", | 575 "g_shared_delayed_integrity_level", &g_shared_delayed_integrity_level, |
| 583 &g_shared_delayed_integrity_level, | 576 sizeof(g_shared_delayed_integrity_level)); |
| 584 sizeof(g_shared_delayed_integrity_level)); | |
| 585 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; | 577 g_shared_delayed_integrity_level = INTEGRITY_LEVEL_LAST; |
| 586 if (SBOX_ALL_OK != ret) | 578 if (SBOX_ALL_OK != ret) |
| 587 return false; | 579 return false; |
| 588 | 580 |
| 589 // Add in delayed mitigations and pseudo-mitigations enforced at startup. | 581 // Add in delayed mitigations and pseudo-mitigations enforced at startup. |
| 590 g_shared_delayed_mitigations = delayed_mitigations_ | | 582 g_shared_delayed_mitigations = |
| 591 FilterPostStartupProcessMitigations(mitigations_); | 583 delayed_mitigations_ | FilterPostStartupProcessMitigations(mitigations_); |
| 592 if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations)) | 584 if (!CanSetProcessMitigationsPostStartup(g_shared_delayed_mitigations)) |
| 593 return false; | 585 return false; |
| 594 | 586 |
| 595 ret = target->TransferVariable("g_shared_delayed_mitigations", | 587 ret = target->TransferVariable("g_shared_delayed_mitigations", |
| 596 &g_shared_delayed_mitigations, | 588 &g_shared_delayed_mitigations, |
| 597 sizeof(g_shared_delayed_mitigations)); | 589 sizeof(g_shared_delayed_mitigations)); |
| 598 g_shared_delayed_mitigations = 0; | 590 g_shared_delayed_mitigations = 0; |
| 599 if (SBOX_ALL_OK != ret) | 591 if (SBOX_ALL_OK != ret) |
| 600 return false; | 592 return false; |
| 601 | 593 |
| 602 AutoLock lock(&lock_); | 594 AutoLock lock(&lock_); |
| 603 targets_.push_back(target); | 595 targets_.push_back(target); |
| 604 return true; | 596 return true; |
| 605 } | 597 } |
| 606 | 598 |
| 607 bool PolicyBase::OnJobEmpty(HANDLE job) { | 599 bool TargetPolicy::OnJobEmpty(HANDLE job) { |
| 608 AutoLock lock(&lock_); | 600 AutoLock lock(&lock_); |
| 609 TargetSet::iterator it; | 601 TargetSet::iterator it; |
| 610 for (it = targets_.begin(); it != targets_.end(); ++it) { | 602 for (it = targets_.begin(); it != targets_.end(); ++it) { |
| 611 if ((*it)->Job() == job) | 603 if ((*it)->Job() == job) |
| 612 break; | 604 break; |
| 613 } | 605 } |
| 614 if (it == targets_.end()) { | 606 if (it == targets_.end()) { |
| 615 return false; | 607 return false; |
| 616 } | 608 } |
| 617 TargetProcess* target = *it; | 609 TargetProcess* target = *it; |
| 618 targets_.erase(it); | 610 targets_.erase(it); |
| 619 delete target; | 611 delete target; |
| 620 return true; | 612 return true; |
| 621 } | 613 } |
| 622 | 614 |
| 623 EvalResult PolicyBase::EvalPolicy(int service, | 615 EvalResult TargetPolicy::EvalPolicy(int service, |
| 624 CountedParameterSetBase* params) { | 616 CountedParameterSetBase* params) { |
| 625 if (NULL != policy_) { | 617 if (NULL != policy_) { |
| 626 if (NULL == policy_->entry[service]) { | 618 if (NULL == policy_->entry[service]) { |
| 627 // There is no policy for this particular service. This is not a big | 619 // There is no policy for this particular service. This is not a big |
| 628 // deal. | 620 // deal. |
| 629 return DENY_ACCESS; | 621 return DENY_ACCESS; |
| 630 } | 622 } |
| 631 for (int i = 0; i < params->count; i++) { | 623 for (int i = 0; i < params->count; i++) { |
| 632 if (!params->parameters[i].IsValid()) { | 624 if (!params->parameters[i].IsValid()) { |
| 633 NOTREACHED(); | 625 NOTREACHED(); |
| 634 return SIGNAL_ALARM; | 626 return SIGNAL_ALARM; |
| 635 } | 627 } |
| 636 } | 628 } |
| 637 PolicyProcessor pol_evaluator(policy_->entry[service]); | 629 PolicyProcessor pol_evaluator(policy_->entry[service]); |
| 638 PolicyResult result = pol_evaluator.Evaluate(kShortEval, | 630 PolicyResult result = |
| 639 params->parameters, | 631 pol_evaluator.Evaluate(kShortEval, params->parameters, params->count); |
| 640 params->count); | |
| 641 if (POLICY_MATCH == result) { | 632 if (POLICY_MATCH == result) { |
| 642 return pol_evaluator.GetAction(); | 633 return pol_evaluator.GetAction(); |
| 643 } | 634 } |
| 644 DCHECK(POLICY_ERROR != result); | 635 DCHECK(POLICY_ERROR != result); |
| 645 } | 636 } |
| 646 | 637 |
| 647 return DENY_ACCESS; | 638 return DENY_ACCESS; |
| 648 } | 639 } |
| 649 | 640 |
| 650 HANDLE PolicyBase::GetStdoutHandle() { | 641 HANDLE TargetPolicy::GetStdoutHandle() { |
| 651 return stdout_handle_; | 642 return stdout_handle_; |
| 652 } | 643 } |
| 653 | 644 |
| 654 HANDLE PolicyBase::GetStderrHandle() { | 645 HANDLE TargetPolicy::GetStderrHandle() { |
| 655 return stderr_handle_; | 646 return stderr_handle_; |
| 656 } | 647 } |
| 657 | 648 |
| 658 bool PolicyBase::SetupAllInterceptions(TargetProcess* target) { | 649 bool TargetPolicy::SetupAllInterceptions(TargetProcess* target) { |
| 659 InterceptionManager manager(target, relaxed_interceptions_); | 650 InterceptionManager manager(target, relaxed_interceptions_); |
| 660 | 651 |
| 661 if (policy_) { | 652 if (policy_) { |
| 662 for (int i = 0; i < IPC_LAST_TAG; i++) { | 653 for (int i = 0; i < IPC_LAST_TAG; i++) { |
| 663 if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i)) | 654 if (policy_->entry[i] && !dispatcher_->SetupService(&manager, i)) |
| 664 return false; | 655 return false; |
| 665 } | 656 } |
| 666 } | 657 } |
| 667 | 658 |
| 668 if (!blacklisted_dlls_.empty()) { | 659 if (!blacklisted_dlls_.empty()) { |
| 669 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); | 660 std::vector<base::string16>::iterator it = blacklisted_dlls_.begin(); |
| 670 for (; it != blacklisted_dlls_.end(); ++it) { | 661 for (; it != blacklisted_dlls_.end(); ++it) { |
| 671 manager.AddToUnloadModules(it->c_str()); | 662 manager.AddToUnloadModules(it->c_str()); |
| 672 } | 663 } |
| 673 } | 664 } |
| 674 | 665 |
| 675 if (!SetupBasicInterceptions(&manager)) | 666 if (!SetupBasicInterceptions(&manager)) |
| 676 return false; | 667 return false; |
| 677 | 668 |
| 678 if (!manager.InitializeInterceptions()) | 669 if (!manager.InitializeInterceptions()) |
| 679 return false; | 670 return false; |
| 680 | 671 |
| 681 // Finally, setup imports on the target so the interceptions can work. | 672 // Finally, setup imports on the target so the interceptions can work. |
| 682 return SetupNtdllImports(target); | 673 return SetupNtdllImports(target); |
| 683 } | 674 } |
| 684 | 675 |
| 685 bool PolicyBase::SetupHandleCloser(TargetProcess* target) { | 676 bool TargetPolicy::SetupHandleCloser(TargetProcess* target) { |
| 686 return handle_closer_.InitializeTargetHandles(target); | 677 return handle_closer_.InitializeTargetHandles(target); |
| 687 } | 678 } |
| 688 | 679 |
| 689 ResultCode PolicyBase::AddRuleInternal(SubSystem subsystem, | 680 ResultCode TargetPolicy::AddRuleInternal(SubSystem subsystem, |
| 690 Semantics semantics, | 681 Semantics semantics, |
| 691 const wchar_t* pattern) { | 682 const wchar_t* pattern) { |
| 692 if (NULL == policy_) { | 683 if (NULL == policy_) { |
| 693 policy_ = MakeBrokerPolicyMemory(); | 684 policy_ = MakeBrokerPolicyMemory(); |
| 694 DCHECK(policy_); | 685 DCHECK(policy_); |
| 695 policy_maker_ = new LowLevelPolicy(policy_); | 686 policy_maker_ = new LowLevelPolicy(policy_); |
| 696 DCHECK(policy_maker_); | 687 DCHECK(policy_maker_); |
| 697 } | 688 } |
| 698 | 689 |
| 699 switch (subsystem) { | 690 switch (subsystem) { |
| 700 case SUBSYS_FILES: { | 691 case SUBSYS_FILES: { |
| 701 if (!file_system_init_) { | 692 if (!file_system_init_) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 break; | 751 break; |
| 761 } | 752 } |
| 762 | 753 |
| 763 default: { return SBOX_ERROR_UNSUPPORTED; } | 754 default: { return SBOX_ERROR_UNSUPPORTED; } |
| 764 } | 755 } |
| 765 | 756 |
| 766 return SBOX_ALL_OK; | 757 return SBOX_ALL_OK; |
| 767 } | 758 } |
| 768 | 759 |
| 769 } // namespace sandbox | 760 } // namespace sandbox |
| OLD | NEW |