Chromium Code Reviews| 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 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 if (ERROR_SUCCESS != result) { | 540 if (ERROR_SUCCESS != result) { |
| 541 return SBOX_ERROR_GENERIC; | 541 return SBOX_ERROR_GENERIC; |
| 542 } | 542 } |
| 543 *job = job_obj.Detach(); | 543 *job = job_obj.Detach(); |
| 544 } else { | 544 } else { |
| 545 *job = NULL; | 545 *job = NULL; |
| 546 } | 546 } |
| 547 return SBOX_ALL_OK; | 547 return SBOX_ALL_OK; |
| 548 } | 548 } |
| 549 | 549 |
| 550 ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { | 550 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, |
| 551 base::win::ScopedHandle* lockdown) { | |
| 551 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && | 552 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer() && |
| 552 lowbox_sid_) { | 553 lowbox_sid_) { |
| 553 return SBOX_ERROR_BAD_PARAMS; | 554 return SBOX_ERROR_BAD_PARAMS; |
| 554 } | 555 } |
| 555 | 556 |
| 556 // Create the 'naked' token. This will be the permanent token associated | 557 // Create the 'naked' token. This will be the permanent token associated |
| 557 // with the process and therefore with any thread that is not impersonating. | 558 // with the process and therefore with any thread that is not impersonating. |
| 558 DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, | 559 HANDLE temp_handle; |
| 560 DWORD result = CreateRestrictedToken(&temp_handle, lockdown_level_, | |
| 559 integrity_level_, PRIMARY); | 561 integrity_level_, PRIMARY); |
| 560 if (ERROR_SUCCESS != result) | 562 if (ERROR_SUCCESS != result) |
| 561 return SBOX_ERROR_GENERIC; | 563 return SBOX_ERROR_GENERIC; |
| 562 | 564 |
| 565 lockdown->Set(temp_handle); | |
| 566 | |
| 563 // If we're launching on the alternate desktop we need to make sure the | 567 // If we're launching on the alternate desktop we need to make sure the |
| 564 // integrity label on the object is no higher than the sandboxed process's | 568 // integrity label on the object is no higher than the sandboxed process's |
| 565 // integrity level. So, we lower the label on the desktop process if it's | 569 // integrity level. So, we lower the label on the desktop process if it's |
| 566 // not already low enough for our process. | 570 // not already low enough for our process. |
| 567 if (alternate_desktop_handle_ && use_alternate_desktop_ && | 571 if (alternate_desktop_handle_ && use_alternate_desktop_ && |
| 568 integrity_level_ != INTEGRITY_LEVEL_LAST && | 572 integrity_level_ != INTEGRITY_LEVEL_LAST && |
| 569 alternate_desktop_integrity_level_label_ < integrity_level_ && | 573 alternate_desktop_integrity_level_label_ < integrity_level_ && |
| 570 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { | 574 base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { |
| 571 // Integrity label enum is reversed (higher level is a lower value). | 575 // Integrity label enum is reversed (higher level is a lower value). |
| 572 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, | 576 static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 583 | 587 |
| 584 // We are maintaining two mutually exclusive approaches. One is to start an | 588 // We are maintaining two mutually exclusive approaches. One is to start an |
| 585 // AppContainer process through StartupInfoEx and other is replacing | 589 // AppContainer process through StartupInfoEx and other is replacing |
| 586 // existing token with LowBox token after process creation. | 590 // existing token with LowBox token after process creation. |
| 587 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { | 591 if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { |
| 588 // Windows refuses to work with an impersonation token. See SetAppContainer | 592 // Windows refuses to work with an impersonation token. See SetAppContainer |
| 589 // implementation for more details. | 593 // implementation for more details. |
| 590 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) | 594 if (lockdown_level_ < USER_LIMITED || lockdown_level_ != initial_level_) |
| 591 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; | 595 return SBOX_ERROR_CANNOT_INIT_APPCONTAINER; |
| 592 | 596 |
| 593 *initial = INVALID_HANDLE_VALUE; | 597 *initial = base::win::ScopedHandle(); |
| 594 return SBOX_ALL_OK; | 598 return SBOX_ALL_OK; |
| 595 } else if (lowbox_sid_) { | 599 } |
| 600 | |
| 601 if (lowbox_sid_) { | |
|
Will Harris
2015/07/10 18:11:31
maybe DCHECK that we are not also using AppContain
rvargas (doing something else)
2015/07/10 18:31:56
Do you mean line the if at line 522? :)
Will Harris
2015/07/10 18:45:07
ah yes. :)
| |
| 596 NtCreateLowBoxToken CreateLowBoxToken = NULL; | 602 NtCreateLowBoxToken CreateLowBoxToken = NULL; |
| 597 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken); | 603 ResolveNTFunctionPtr("NtCreateLowBoxToken", &CreateLowBoxToken); |
| 598 OBJECT_ATTRIBUTES obj_attr; | 604 OBJECT_ATTRIBUTES obj_attr; |
| 599 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); | 605 InitializeObjectAttributes(&obj_attr, NULL, 0, NULL, NULL); |
| 600 HANDLE token_lowbox = NULL; | 606 HANDLE token_lowbox = NULL; |
| 601 | 607 |
| 602 if (!lowbox_directory_.IsValid()) | 608 if (!lowbox_directory_.IsValid()) |
| 603 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); | 609 lowbox_directory_.Set(CreateLowBoxObjectDirectory(lowbox_sid_)); |
| 604 DCHECK(lowbox_directory_.IsValid()); | 610 DCHECK(lowbox_directory_.IsValid()); |
| 605 | 611 |
| 606 // The order of handles isn't important in the CreateLowBoxToken call. | 612 // The order of handles isn't important in the CreateLowBoxToken call. |
| 607 // The kernel will maintain a reference to the object directory handle. | 613 // The kernel will maintain a reference to the object directory handle. |
| 608 HANDLE saved_handles[1] = {lowbox_directory_.Get()}; | 614 HANDLE saved_handles[1] = {lowbox_directory_.Get()}; |
| 609 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; | 615 DWORD saved_handles_count = lowbox_directory_.IsValid() ? 1 : 0; |
| 610 | 616 |
| 611 NTSTATUS status = CreateLowBoxToken(&token_lowbox, *lockdown, | 617 NTSTATUS status = CreateLowBoxToken(&token_lowbox, lockdown->Get(), |
| 612 TOKEN_ALL_ACCESS, &obj_attr, | 618 TOKEN_ALL_ACCESS, &obj_attr, |
| 613 lowbox_sid_, 0, NULL, | 619 lowbox_sid_, 0, NULL, |
| 614 saved_handles_count, saved_handles); | 620 saved_handles_count, saved_handles); |
| 615 if (!NT_SUCCESS(status)) | 621 if (!NT_SUCCESS(status)) |
| 616 return SBOX_ERROR_GENERIC; | 622 return SBOX_ERROR_GENERIC; |
| 617 | 623 |
| 618 DCHECK(token_lowbox); | 624 DCHECK(token_lowbox); |
| 619 ::CloseHandle(*lockdown); | 625 lockdown->Set(token_lowbox); |
|
Will Harris
2015/07/10 18:11:31
scoped handles really does make this a lot more el
| |
| 620 *lockdown = token_lowbox; | |
| 621 } | 626 } |
| 622 | 627 |
| 623 // Create the 'better' token. We use this token as the one that the main | 628 // Create the 'better' token. We use this token as the one that the main |
| 624 // thread uses when booting up the process. It should contain most of | 629 // thread uses when booting up the process. It should contain most of |
| 625 // what we need (before reaching main( )) | 630 // what we need (before reaching main( )) |
| 626 result = CreateRestrictedToken(initial, initial_level_, | 631 result = CreateRestrictedToken(&temp_handle, initial_level_, |
| 627 integrity_level_, IMPERSONATION); | 632 integrity_level_, IMPERSONATION); |
| 628 if (ERROR_SUCCESS != result) { | 633 if (ERROR_SUCCESS != result) |
| 629 ::CloseHandle(*lockdown); | |
| 630 return SBOX_ERROR_GENERIC; | 634 return SBOX_ERROR_GENERIC; |
| 631 } | 635 |
| 636 initial->Set(temp_handle); | |
| 632 return SBOX_ALL_OK; | 637 return SBOX_ALL_OK; |
| 633 } | 638 } |
| 634 | 639 |
| 635 const AppContainerAttributes* PolicyBase::GetAppContainer() const { | 640 const AppContainerAttributes* PolicyBase::GetAppContainer() const { |
| 636 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) | 641 if (!appcontainer_list_.get() || !appcontainer_list_->HasAppContainer()) |
| 637 return NULL; | 642 return NULL; |
| 638 | 643 |
| 639 return appcontainer_list_.get(); | 644 return appcontainer_list_.get(); |
| 640 } | 645 } |
| 641 | 646 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 break; | 883 break; |
| 879 } | 884 } |
| 880 | 885 |
| 881 default: { return SBOX_ERROR_UNSUPPORTED; } | 886 default: { return SBOX_ERROR_UNSUPPORTED; } |
| 882 } | 887 } |
| 883 | 888 |
| 884 return SBOX_ALL_OK; | 889 return SBOX_ALL_OK; |
| 885 } | 890 } |
| 886 | 891 |
| 887 } // namespace sandbox | 892 } // namespace sandbox |
| OLD | NEW |