| 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_base.h" |
| 6 | 6 |
| 7 #include <sddl.h> | 7 #include <sddl.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/macros.h" | 13 #include "base/macros.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/win/windows_version.h" | 16 #include "base/win/windows_version.h" |
| 17 #include "sandbox/win/src/app_container.h" | |
| 18 #include "sandbox/win/src/filesystem_policy.h" | 17 #include "sandbox/win/src/filesystem_policy.h" |
| 19 #include "sandbox/win/src/handle_policy.h" | 18 #include "sandbox/win/src/handle_policy.h" |
| 20 #include "sandbox/win/src/interception.h" | 19 #include "sandbox/win/src/interception.h" |
| 21 #include "sandbox/win/src/job.h" | 20 #include "sandbox/win/src/job.h" |
| 22 #include "sandbox/win/src/named_pipe_policy.h" | 21 #include "sandbox/win/src/named_pipe_policy.h" |
| 23 #include "sandbox/win/src/policy_broker.h" | 22 #include "sandbox/win/src/policy_broker.h" |
| 24 #include "sandbox/win/src/policy_engine_processor.h" | 23 #include "sandbox/win/src/policy_engine_processor.h" |
| 25 #include "sandbox/win/src/policy_low_level.h" | 24 #include "sandbox/win/src/policy_low_level.h" |
| 26 #include "sandbox/win/src/process_mitigations.h" | 25 #include "sandbox/win/src/process_mitigations.h" |
| 27 #include "sandbox/win/src/process_mitigations_win32k_policy.h" | 26 #include "sandbox/win/src/process_mitigations_win32k_policy.h" |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 IntegrityLevel PolicyBase::GetIntegrityLevel() const { | 304 IntegrityLevel PolicyBase::GetIntegrityLevel() const { |
| 306 return integrity_level_; | 305 return integrity_level_; |
| 307 } | 306 } |
| 308 | 307 |
| 309 ResultCode PolicyBase::SetDelayedIntegrityLevel( | 308 ResultCode PolicyBase::SetDelayedIntegrityLevel( |
| 310 IntegrityLevel integrity_level) { | 309 IntegrityLevel integrity_level) { |
| 311 delayed_integrity_level_ = integrity_level; | 310 delayed_integrity_level_ = integrity_level; |
| 312 return SBOX_ALL_OK; | 311 return SBOX_ALL_OK; |
| 313 } | 312 } |
| 314 | 313 |
| 315 ResultCode PolicyBase::SetAppContainer(const wchar_t* sid) { | |
| 316 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) | |
| 317 return SBOX_ALL_OK; | |
| 318 | |
| 319 // SetLowBox and SetAppContainer are mutually exclusive. | |
| 320 if (lowbox_sid_) | |
| 321 return SBOX_ERROR_UNSUPPORTED; | |
| 322 | |
| 323 // Windows refuses to work with an impersonation token for a process inside | |
| 324 // an AppContainer. If the caller wants to use a more privileged initial | |
| 325 // token, or if the lockdown level will prevent the process from starting, | |
| 326 // we have to fail the operation. | |
| 327 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) | |
| 328 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; | |
| 329 | |
| 330 DCHECK(!appcontainer_list_.get()); | |
| 331 appcontainer_list_.reset(new AppContainerAttributes); | |
| 332 ResultCode rv = appcontainer_list_->SetAppContainer(sid, capabilities_); | |
| 333 if (rv != SBOX_ALL_OK) | |
| 334 return rv; | |
| 335 | |
| 336 return SBOX_ALL_OK; | |
| 337 } | |
| 338 | |
| 339 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { | 314 ResultCode PolicyBase::SetCapability(const wchar_t* sid) { |
| 340 capabilities_.push_back(sid); | 315 capabilities_.push_back(sid); |
| 341 return SBOX_ALL_OK; | 316 return SBOX_ALL_OK; |
| 342 } | 317 } |
| 343 | 318 |
| 344 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { | 319 ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { |
| 345 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) | 320 if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8) |
| 346 return SBOX_ERROR_UNSUPPORTED; | 321 return SBOX_ERROR_UNSUPPORTED; |
| 347 | 322 |
| 348 // SetLowBox and SetAppContainer are mutually exclusive. | |
| 349 if (appcontainer_list_.get()) | |
| 350 return SBOX_ERROR_UNSUPPORTED; | |
| 351 | |
| 352 DCHECK(sid); | 323 DCHECK(sid); |
| 353 | |
| 354 if (lowbox_sid_) | 324 if (lowbox_sid_) |
| 355 return SBOX_ERROR_BAD_PARAMS; | 325 return SBOX_ERROR_BAD_PARAMS; |
| 356 | 326 |
| 357 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) | 327 if (!ConvertStringSidToSid(sid, &lowbox_sid_)) |
| 358 return SBOX_ERROR_GENERIC; | 328 return SBOX_ERROR_GENERIC; |
| 359 | 329 |
| 360 return SBOX_ALL_OK; | 330 return SBOX_ALL_OK; |
| 361 } | 331 } |
| 362 | 332 |
| 363 ResultCode PolicyBase::SetProcessMitigations( | 333 ResultCode PolicyBase::SetProcessMitigations( |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 *job = job_obj.Take(); | 425 *job = job_obj.Take(); |
| 456 } else { | 426 } else { |
| 457 *job = base::win::ScopedHandle(); | 427 *job = base::win::ScopedHandle(); |
| 458 } | 428 } |
| 459 return SBOX_ALL_OK; | 429 return SBOX_ALL_OK; |
| 460 } | 430 } |
| 461 | 431 |
| 462 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, | 432 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, |
| 463 base::win::ScopedHandle* lockdown, | 433 base::win::ScopedHandle* lockdown, |
| 464 base::win::ScopedHandle* lowbox) { | 434 base::win::ScopedHandle* lowbox) { |
| 465 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && | |
| 466 lowbox_sid_) { | |
| 467 return SBOX_ERROR_BAD_PARAMS; | |
| 468 } | |
| 469 | |
| 470 // Create the 'naked' token. This will be the permanent token associated | 435 // Create the 'naked' token. This will be the permanent token associated |
| 471 // with the process and therefore with any thread that is not impersonating. | 436 // with the process and therefore with any thread that is not impersonating. |
| 472 DWORD result = | 437 DWORD result = |
| 473 CreateRestrictedToken(lockdown_level_, integrity_level_, PRIMARY, | 438 CreateRestrictedToken(lockdown_level_, integrity_level_, PRIMARY, |
| 474 lockdown_default_dacl_, lockdown); | 439 lockdown_default_dacl_, lockdown); |
| 475 if (ERROR_SUCCESS != result) | 440 if (ERROR_SUCCESS != result) |
| 476 return SBOX_ERROR_GENERIC; | 441 return SBOX_ERROR_GENERIC; |
| 477 | 442 |
| 478 // If we're launching on the alternate desktop we need to make sure the | 443 // If we're launching on the alternate desktop we need to make sure the |
| 479 // integrity label on the object is no higher than the sandboxed process's | 444 // integrity label on the object is no higher than the sandboxed process's |
| 480 // integrity level. So, we lower the label on the desktop process if it's | 445 // integrity level. So, we lower the label on the desktop process if it's |
| 481 // not already low enough for our process. | 446 // not already low enough for our process. |
| 482 if (alternate_desktop_handle_ && use_alternate_desktop_ && | 447 if (alternate_desktop_handle_ && use_alternate_desktop_ && |
| 483 integrity_level_ != INTEGRITY_LEVEL_LAST && | 448 integrity_level_ != INTEGRITY_LEVEL_LAST && |
| 484 alternate_desktop_integrity_level_label_ < integrity_level_) { | 449 alternate_desktop_integrity_level_label_ < integrity_level_) { |
| 485 // Integrity label enum is reversed (higher level is a lower value). | 450 // Integrity label enum is reversed (higher level is a lower value). |
| 486 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, | 451 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
| 487 "Integrity level ordering reversed."); | 452 "Integrity level ordering reversed."); |
| 488 result = SetObjectIntegrityLabel(alternate_desktop_handle_, | 453 result = SetObjectIntegrityLabel(alternate_desktop_handle_, |
| 489 SE_WINDOW_OBJECT, | 454 SE_WINDOW_OBJECT, |
| 490 L"", | 455 L"", |
| 491 GetIntegrityLevelString(integrity_level_)); | 456 GetIntegrityLevelString(integrity_level_)); |
| 492 if (ERROR_SUCCESS != result) | 457 if (ERROR_SUCCESS != result) |
| 493 return SBOX_ERROR_GENERIC; | 458 return SBOX_ERROR_GENERIC; |
| 494 | 459 |
| 495 alternate_desktop_integrity_level_label_ = integrity_level_; | 460 alternate_desktop_integrity_level_label_ = integrity_level_; |
| 496 } | 461 } |
| 497 | 462 |
| 498 // We are maintaining two mutually exclusive approaches. One is to start an | |
| 499 // AppContainer process through StartupInfoEx and other is replacing | |
| 500 // existing token with LowBox token after process creation. | |
| 501 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { | |
| 502 // Windows refuses to work with an impersonation token. See SetAppContainer | |
| 503 // implementation for more details. | |
| 504 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) | |
| 505 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; | |
| 506 | |
| 507 *initial = base::win::ScopedHandle(); | |
| 508 return SBOX_ALL_OK; | |
| 509 } | |
| 510 | |
| 511 if (lowbox_sid_) { | 463 if (lowbox_sid_) { |
| 512 NtCreateLowBoxToken CreateLowBoxToken = NULL; | 464 NtCreateLowBoxToken CreateLowBoxToken = NULL; |
| 513 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken); | 465 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken); |
| 514 OBJECT_ATTRIBUTES obj_attr; | 466 OBJECT_ATTRIBUTES obj_attr; |
| 515 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); | 467 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); |
| 516 HANDLE token_lowbox = NULL; | 468 HANDLE token_lowbox = NULL; |
| 517 | 469 |
| 518 if (!lowbox_directory_.IsValid()) | 470 if (!lowbox_directory_.IsValid()) |
| 519 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); | 471 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); |
| 520 DCHECK(lowbox_directory_.IsValid()); | 472 DCHECK(lowbox_directory_.IsValid()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 540 // what we need (before reaching main( )) | 492 // what we need (before reaching main( )) |
| 541 result = | 493 result = |
| 542 CreateRestrictedToken(initial_level_, integrity_level_, IMPERSONATION, | 494 CreateRestrictedToken(initial_level_, integrity_level_, IMPERSONATION, |
| 543 lockdown_default_dacl_, initial); | 495 lockdown_default_dacl_, initial); |
| 544 if (ERROR_SUCCESS != result) | 496 if (ERROR_SUCCESS != result) |
| 545 return SBOX_ERROR_GENERIC; | 497 return SBOX_ERROR_GENERIC; |
| 546 | 498 |
| 547 return SBOX_ALL_OK; | 499 return SBOX_ALL_OK; |
| 548 } | 500 } |
| 549 | 501 |
| 550 const AppContainerAttributes* PolicyBase::GetAppContainer() const { | |
| 551 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) | |
| 552 return NULL; | |
| 553 | |
| 554 return appcontainer_list_.get(); | |
| 555 } | |
| 556 | |
| 557 PSID PolicyBase::GetLowBoxSid() const { | 502 PSID PolicyBase::GetLowBoxSid() const { |
| 558 return lowbox_sid_; | 503 return lowbox_sid_; |
| 559 } | 504 } |
| 560 | 505 |
| 561 bool PolicyBase::AddTarget(TargetProcess* target) { | 506 bool PolicyBase::AddTarget(TargetProcess* target) { |
| 562 if (NULL != policy_) | 507 if (NULL != policy_) |
| 563 policy_maker_->Done(); | 508 policy_maker_->Done(); |
| 564 | 509 |
| 565 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), | 510 if (!ApplyProcessMitigationsToSuspendedProcess(target->Process(), |
| 566 mitigations_)) { | 511 mitigations_)) { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 break; | 713 break; |
| 769 } | 714 } |
| 770 | 715 |
| 771 default: { return SBOX_ERROR_UNSUPPORTED; } | 716 default: { return SBOX_ERROR_UNSUPPORTED; } |
| 772 } | 717 } |
| 773 | 718 |
| 774 return SBOX_ALL_OK; | 719 return SBOX_ALL_OK; |
| 775 } | 720 } |
| 776 | 721 |
| 777 } // namespace sandbox | 722 } // namespace sandbox |
| OLD | NEW |