diff options
-rw-r--r-- | content/common/sandbox_win.cc | 1 | ||||
-rw-r--r-- | sandbox/win/src/integrity_level_test.cc | 1 | ||||
-rw-r--r-- | sandbox/win/src/restricted_token_utils.h | 4 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy_base.cc | 26 | ||||
-rw-r--r-- | sandbox/win/src/sandbox_policy_base.h | 1 | ||||
-rw-r--r-- | sandbox/win/tests/validation_tests/suite.cc | 3 |
6 files changed, 34 insertions, 2 deletions
diff --git a/content/common/sandbox_win.cc b/content/common/sandbox_win.cc index d733213..68a00dd 100644 --- a/content/common/sandbox_win.cc +++ b/content/common/sandbox_win.cc @@ -361,6 +361,7 @@ bool AddPolicyForSandboxedProcess(sandbox::TargetPolicy* policy) { policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); // Prevents the renderers from manipulating low-integrity processes. policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED); + policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(true)) { DLOG(WARNING) << "Failed to apply desktop security to the renderer"; diff --git a/sandbox/win/src/integrity_level_test.cc b/sandbox/win/src/integrity_level_test.cc index 67ea9de..f962033 100644 --- a/sandbox/win/src/integrity_level_test.cc +++ b/sandbox/win/src/integrity_level_test.cc @@ -52,6 +52,7 @@ TEST(IntegrityLevelTest, TestLowILReal) { runner.SetTimeout(INFINITE); + runner.GetPolicy()->SetAlternateDesktop(true); runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckIntegrityLevel")); diff --git a/sandbox/win/src/restricted_token_utils.h b/sandbox/win/src/restricted_token_utils.h index f2a280a..69462b4 100644 --- a/sandbox/win/src/restricted_token_utils.h +++ b/sandbox/win/src/restricted_token_utils.h @@ -73,6 +73,10 @@ DWORD SetObjectIntegrityLabel(HANDLE handle, SE_OBJECT_TYPE type, // than the current integrity level, the function will fail. DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level); +// Returns the integrity level SDDL string associated with a given +// IntegrityLevel value. +const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level); + // Sets the integrity level on the current process on Vista. It returns without // failing on XP. If the integrity level that you specify is greater than the // current integrity level, the function will fail. diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc index 711fafc..7b9262b 100644 --- a/sandbox/win/src/sandbox_policy_base.cc +++ b/sandbox/win/src/sandbox_policy_base.cc @@ -4,6 +4,8 @@ #include "sandbox/win/src/sandbox_policy_base.h" +#include <sddl.h> + #include "base/basictypes.h" #include "base/callback.h" #include "base/logging.h" @@ -75,6 +77,8 @@ SANDBOX_INTERCEPT MitigationFlags g_shared_delayed_mitigations; // Initializes static members. HWINSTA PolicyBase::alternate_winstation_handle_ = NULL; HDESK PolicyBase::alternate_desktop_handle_ = NULL; +IntegrityLevel PolicyBase::alternate_desktop_integrity_level_label_ = + INTEGRITY_LEVEL_SYSTEM; PolicyBase::PolicyBase() : ref_count(1), @@ -517,8 +521,28 @@ ResultCode PolicyBase::MakeTokens(HANDLE* initial, HANDLE* lockdown) { // with the process and therefore with any thread that is not impersonating. DWORD result = CreateRestrictedToken(lockdown, lockdown_level_, integrity_level_, PRIMARY); - if (ERROR_SUCCESS != result) { + if (ERROR_SUCCESS != result) return SBOX_ERROR_GENERIC; + + // If we're launching on the alternate desktop we need to make sure the + // integrity label on the object is no higher than the sandboxed process's + // integrity level. So, we lower the label on the desktop process if it's + // not already low enough for our process. + if (use_alternate_desktop_ && + integrity_level_ != INTEGRITY_LEVEL_LAST && + alternate_desktop_integrity_level_label_ < integrity_level_ && + base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) { + // Integrity label enum is reversed (higher level is a lower value). + static_assert(INTEGRITY_LEVEL_SYSTEM < INTEGRITY_LEVEL_UNTRUSTED, + "Integrity level ordering reversed."); + result = SetObjectIntegrityLabel(alternate_desktop_handle_, + SE_WINDOW_OBJECT, + L"", + GetIntegrityLevelString(integrity_level_)); + if (ERROR_SUCCESS != result) + return SBOX_ERROR_GENERIC; + + alternate_desktop_integrity_level_label_ = integrity_level_; } if (appcontainer_list_.get() && appcontainer_list_->HasAppContainer()) { diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h index 540f261..952df0d 100644 --- a/sandbox/win/src/sandbox_policy_base.h +++ b/sandbox/win/src/sandbox_policy_base.h @@ -157,6 +157,7 @@ class PolicyBase : public Dispatcher, public TargetPolicy { static HDESK alternate_desktop_handle_; static HWINSTA alternate_winstation_handle_; + static IntegrityLevel alternate_desktop_integrity_level_label_; DISALLOW_COPY_AND_ASSIGN(PolicyBase); }; diff --git a/sandbox/win/tests/validation_tests/suite.cc b/sandbox/win/tests/validation_tests/suite.cc index 4a8ae43..df50c56 100644 --- a/sandbox/win/tests/validation_tests/suite.cc +++ b/sandbox/win/tests/validation_tests/suite.cc @@ -112,6 +112,7 @@ TEST(ValidationSuite, TestRegistry) { TEST(ValidationSuite, TestDesktop) { TestRunner runner; runner.GetPolicy()->SetAlternateDesktop(true); + runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL")); EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL")); } @@ -129,7 +130,7 @@ TEST(ValidationSuite, TestAlternateDesktop) { wchar_t command[1024] = {0}; runner.SetTimeout(3600000); runner.GetPolicy()->SetAlternateDesktop(true); - runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED); + runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW); base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop(); desktop_name = desktop_name.substr(desktop_name.find('\\') + 1); wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str()); |