Commit c1ce57ea authored by James Forshaw's avatar James Forshaw Committed by Commit Bot

[Windows] Add support for random restricted SID.

This CL adds support to the sandbox to define a random restricted SID
for a single process. This combined with modifications to the DACL allows
a process to access itself but no other process defined using the same
lockdown type. This CL does not currently enable it for any sandbox type.

Bug: 1057218
Change-Id: Iadd98cdc7331f5fe0c9ae8f414be8af64c5eeb1c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2085751Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Commit-Queue: James Forshaw <forshaw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747008}
parent 5d7e77c0
...@@ -146,6 +146,14 @@ DWORD RestrictedToken::GetRestrictedToken( ...@@ -146,6 +146,14 @@ DWORD RestrictedToken::GetRestrictedToken(
} }
} }
for (const auto& default_dacl_sid : sids_for_default_dacl_) {
if (!AddSidToDefaultDacl(new_token.Get(), std::get<0>(default_dacl_sid),
std::get<1>(default_dacl_sid),
std::get<2>(default_dacl_sid))) {
return ::GetLastError();
}
}
// Add user to default dacl. // Add user to default dacl.
if (!AddUserSidToDefaultDacl(new_token.Get(), GENERIC_ALL)) if (!AddUserSidToDefaultDacl(new_token.Get(), GENERIC_ALL))
return ::GetLastError(); return ::GetLastError();
...@@ -410,4 +418,15 @@ void RestrictedToken::SetLockdownDefaultDacl() { ...@@ -410,4 +418,15 @@ void RestrictedToken::SetLockdownDefaultDacl() {
lockdown_default_dacl_ = true; lockdown_default_dacl_ = true;
} }
DWORD RestrictedToken::AddDefaultDaclSid(const Sid& sid,
ACCESS_MODE access_mode,
ACCESS_MASK access) {
DCHECK(init_);
if (!init_)
return ERROR_NO_TOKEN;
sids_for_default_dacl_.push_back(std::make_tuple(sid, access_mode, access));
return ERROR_SUCCESS;
}
} // namespace sandbox } // namespace sandbox
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <tuple>
#include "base/macros.h" #include "base/macros.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
...@@ -174,6 +175,12 @@ class RestrictedToken { ...@@ -174,6 +175,12 @@ class RestrictedToken {
// default DACL when created. // default DACL when created.
void SetLockdownDefaultDacl(); void SetLockdownDefaultDacl();
// Add a SID to the default DACL. These SIDs are added regardless of the
// SetLockdownDefaultDacl state.
DWORD AddDefaultDaclSid(const Sid& sid,
ACCESS_MODE access_mode,
ACCESS_MASK access);
private: private:
// The list of restricting sids in the restricted token. // The list of restricting sids in the restricted token.
std::vector<Sid> sids_to_restrict_; std::vector<Sid> sids_to_restrict_;
...@@ -181,6 +188,8 @@ class RestrictedToken { ...@@ -181,6 +188,8 @@ class RestrictedToken {
std::vector<LUID> privileges_to_disable_; std::vector<LUID> privileges_to_disable_;
// The list of sids to mark as Deny Only in the restricted token. // The list of sids to mark as Deny Only in the restricted token.
std::vector<Sid> sids_for_deny_only_; std::vector<Sid> sids_for_deny_only_;
// The list of sids to add to the default DACL of the restricted token.
std::vector<std::tuple<Sid, ACCESS_MODE, ACCESS_MASK>> sids_for_default_dacl_;
// The token to restrict. Can only be set in a constructor. // The token to restrict. Can only be set in a constructor.
base::win::ScopedHandle effective_token_; base::win::ScopedHandle effective_token_;
// The token integrity level. Only valid on Vista. // The token integrity level. Only valid on Vista.
......
...@@ -42,6 +42,44 @@ int RunOpenProcessTest(bool unsandboxed, ...@@ -42,6 +42,44 @@ int RunOpenProcessTest(bool unsandboxed,
.c_str()); .c_str());
} }
int RunRestrictedOpenProcessTest(bool unsandboxed,
bool lockdown_dacl,
DWORD access_mask) {
TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
if (lockdown_dacl) {
runner.GetPolicy()->SetLockdownDefaultDacl();
runner.GetPolicy()->AddRestrictingRandomSid();
}
runner.SetAsynchronous(true);
// This spins up a GPU level process, we don't care about the result.
runner.RunTest(L"IntegrationTestsTest_args 1");
TestRunner runner2(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
runner2.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
runner2.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
runner2.SetUnsandboxed(unsandboxed);
return runner2.RunTest(
base::StringPrintf(L"RestrictedTokenTest_openprocess %d 0x%08X",
runner.process_id(), access_mask)
.c_str());
}
int RunRestrictedSelfOpenProcessTest(bool add_random_sid, DWORD access_mask) {
TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LIMITED);
runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_LOW);
runner.GetPolicy()->SetIntegrityLevel(INTEGRITY_LEVEL_LOW);
runner.GetPolicy()->SetLockdownDefaultDacl();
if (add_random_sid)
runner.GetPolicy()->AddRestrictingRandomSid();
return runner.RunTest(
base::StringPrintf(L"RestrictedTokenTest_currentprocess_dup 0x%08X",
access_mask)
.c_str());
}
} // namespace } // namespace
// Opens a process based on a PID and access mask passed on the command line. // Opens a process based on a PID and access mask passed on the command line.
...@@ -62,6 +100,31 @@ SBOX_TESTS_COMMAND int RestrictedTokenTest_openprocess(int argc, ...@@ -62,6 +100,31 @@ SBOX_TESTS_COMMAND int RestrictedTokenTest_openprocess(int argc,
return SBOX_TEST_DENIED; return SBOX_TEST_DENIED;
} }
// Opens a process through duplication. This is to avoid the OpenProcess hook.
SBOX_TESTS_COMMAND int RestrictedTokenTest_currentprocess_dup(int argc,
wchar_t** argv) {
if (argc < 1)
return SBOX_TEST_NOT_FOUND;
DWORD desired_access = wcstoul(argv[0], nullptr, 0);
HANDLE dup_handle;
if (!::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentProcess(),
::GetCurrentProcess(), &dup_handle, 0, FALSE, 0)) {
return SBOX_TEST_FIRST_ERROR;
}
base::win::ScopedHandle process_handle(dup_handle);
if (::DuplicateHandle(::GetCurrentProcess(), process_handle.Get(),
::GetCurrentProcess(), &dup_handle, desired_access,
FALSE, 0)) {
::CloseHandle(dup_handle);
return SBOX_TEST_SUCCEEDED;
}
if (::GetLastError() != ERROR_ACCESS_DENIED)
return SBOX_TEST_SECOND_ERROR;
return SBOX_TEST_DENIED;
}
// Opens a the process token and checks if it's restricted. // Opens a the process token and checks if it's restricted.
SBOX_TESTS_COMMAND int RestrictedTokenTest_IsRestricted(int argc, SBOX_TESTS_COMMAND int RestrictedTokenTest_IsRestricted(int argc,
wchar_t** argv) { wchar_t** argv) {
...@@ -106,4 +169,30 @@ TEST(RestrictedTokenTest, CheckNonAdminRestricted) { ...@@ -106,4 +169,30 @@ TEST(RestrictedTokenTest, CheckNonAdminRestricted) {
runner_restricted.RunTest(L"RestrictedTokenTest_IsRestricted")); runner_restricted.RunTest(L"RestrictedTokenTest_IsRestricted"));
} }
TEST(RestrictedTokenTest, OpenProcessSameSandboxRandomSid) {
// Test process to process open when not using random SID.
ASSERT_EQ(SBOX_TEST_SUCCEEDED,
RunRestrictedOpenProcessTest(false, false, GENERIC_ALL));
// Test process to process open when using random SID.
ASSERT_EQ(SBOX_TEST_DENIED,
RunRestrictedOpenProcessTest(false, true, MAXIMUM_ALLOWED));
// Test process to process open when not using random SID and opening from
// unsandboxed.
ASSERT_EQ(SBOX_TEST_SUCCEEDED,
RunRestrictedOpenProcessTest(true, false, GENERIC_ALL));
// Test process to process open when using random SID and opening from
// unsandboxed.
ASSERT_EQ(SBOX_TEST_SUCCEEDED,
RunRestrictedOpenProcessTest(true, true, GENERIC_ALL));
}
TEST(RestrictedTokenTest, OpenProcessSelfRandomSid) {
// Test process can't open self when not using random SID.
ASSERT_EQ(SBOX_TEST_DENIED,
RunRestrictedSelfOpenProcessTest(false, PROCESS_ALL_ACCESS));
// Test process can open self when using random SID.
ASSERT_EQ(SBOX_TEST_SUCCEEDED,
RunRestrictedSelfOpenProcessTest(true, PROCESS_ALL_ACCESS));
}
} // namespace sandbox } // namespace sandbox
...@@ -20,11 +20,19 @@ namespace sandbox { ...@@ -20,11 +20,19 @@ namespace sandbox {
namespace { namespace {
void TestDefaultDalc(bool restricted_required) { void TestDefaultDalc(bool restricted_required, bool additional_sid_required) {
RestrictedToken token; RestrictedToken token;
ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS), token.Init(nullptr)); ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS), token.Init(nullptr));
if (!restricted_required) if (!restricted_required)
token.SetLockdownDefaultDacl(); token.SetLockdownDefaultDacl();
ATL::CSid additional_sid = ATL::Sids::Guests();
ATL::CSid additional_sid2 = ATL::Sids::Batch();
if (additional_sid_required) {
token.AddDefaultDaclSid(Sid(additional_sid.GetPSID()), GRANT_ACCESS,
READ_CONTROL);
token.AddDefaultDaclSid(Sid(additional_sid2.GetPSID()), DENY_ACCESS,
GENERIC_ALL);
}
ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS), ASSERT_EQ(static_cast<DWORD>(ERROR_SUCCESS),
token.AddRestrictingSid(ATL::Sids::World().GetPSID())); token.AddRestrictingSid(ATL::Sids::World().GetPSID()));
...@@ -44,20 +52,31 @@ void TestDefaultDalc(bool restricted_required) { ...@@ -44,20 +52,31 @@ void TestDefaultDalc(bool restricted_required) {
bool restricted_found = false; bool restricted_found = false;
bool logon_sid_found = false; bool logon_sid_found = false;
bool additional_sid_found = false;
bool additional_sid2_found = false;
unsigned int ace_count = dacl.GetAceCount(); unsigned int ace_count = dacl.GetAceCount();
for (unsigned int i = 0; i < ace_count; ++i) { for (unsigned int i = 0; i < ace_count; ++i) {
ATL::CSid sid; ATL::CSid sid;
ACCESS_MASK mask = 0; ACCESS_MASK mask = 0;
dacl.GetAclEntry(i, &sid, &mask); BYTE ace_type = 0;
dacl.GetAclEntry(i, &sid, &mask, &ace_type);
if (sid == ATL::Sids::RestrictedCode() && mask == GENERIC_ALL) { if (sid == ATL::Sids::RestrictedCode() && mask == GENERIC_ALL) {
restricted_found = true; restricted_found = true;
} else if (sid == logon_sid) { } else if (sid == logon_sid) {
logon_sid_found = true; logon_sid_found = true;
} else if (sid == additional_sid && mask == READ_CONTROL &&
ace_type == ACCESS_ALLOWED_ACE_TYPE) {
additional_sid_found = true;
} else if (sid == additional_sid2 && mask == GENERIC_ALL &&
ace_type == ACCESS_DENIED_ACE_TYPE) {
additional_sid2_found = true;
} }
} }
ASSERT_EQ(restricted_required, restricted_found); ASSERT_EQ(restricted_required, restricted_found);
ASSERT_EQ(additional_sid_required, additional_sid_found);
ASSERT_EQ(additional_sid_required, additional_sid2_found);
if (!restricted_required) if (!restricted_required)
ASSERT_FALSE(logon_sid_found); ASSERT_FALSE(logon_sid_found);
} }
...@@ -325,13 +344,24 @@ TEST(RestrictedTokenTest, ResultToken) { ...@@ -325,13 +344,24 @@ TEST(RestrictedTokenTest, ResultToken) {
// Verifies that the token created has "Restricted" in its default dacl. // Verifies that the token created has "Restricted" in its default dacl.
TEST(RestrictedTokenTest, DefaultDacl) { TEST(RestrictedTokenTest, DefaultDacl) {
TestDefaultDalc(true); TestDefaultDalc(true, false);
} }
// Verifies that the token created does not have "Restricted" in its default // Verifies that the token created does not have "Restricted" in its default
// dacl. // dacl.
TEST(RestrictedTokenTest, DefaultDaclLockdown) { TEST(RestrictedTokenTest, DefaultDaclLockdown) {
TestDefaultDalc(false); TestDefaultDalc(false, false);
}
// Verifies that the token created has an additional SID in its default dacl.
TEST(RestrictedTokenTest, DefaultDaclWithAddition) {
TestDefaultDalc(true, true);
}
// Verifies that the token created does not have "Restricted" in its default
// dacl and also has an additional SID.
TEST(RestrictedTokenTest, DefaultDaclLockdownWithAddition) {
TestDefaultDalc(false, true);
} }
// Tests the method "AddSidForDenyOnly". // Tests the method "AddSidForDenyOnly".
......
...@@ -56,11 +56,18 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -56,11 +56,18 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
IntegrityLevel integrity_level, IntegrityLevel integrity_level,
TokenType token_type, TokenType token_type,
bool lockdown_default_dacl, bool lockdown_default_dacl,
PSID unique_restricted_sid,
base::win::ScopedHandle* token) { base::win::ScopedHandle* token) {
RestrictedToken restricted_token; RestrictedToken restricted_token;
restricted_token.Init(effective_token); restricted_token.Init(effective_token);
if (lockdown_default_dacl) if (lockdown_default_dacl)
restricted_token.SetLockdownDefaultDacl(); restricted_token.SetLockdownDefaultDacl();
if (unique_restricted_sid) {
restricted_token.AddDefaultDaclSid(Sid(unique_restricted_sid), GRANT_ACCESS,
GENERIC_ALL);
restricted_token.AddDefaultDaclSid(Sid(WinCreatorOwnerRightsSid),
GRANT_ACCESS, READ_CONTROL);
}
std::vector<std::wstring> privilege_exceptions; std::vector<std::wstring> privilege_exceptions;
std::vector<Sid> sid_exceptions; std::vector<Sid> sid_exceptions;
...@@ -105,6 +112,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -105,6 +112,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
restricted_token.AddRestrictingSid(WinRestrictedCodeSid); restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
restricted_token.AddRestrictingSidCurrentUser(); restricted_token.AddRestrictingSidCurrentUser();
restricted_token.AddRestrictingSidLogonSession(); restricted_token.AddRestrictingSidLogonSession();
if (unique_restricted_sid)
restricted_token.AddRestrictingSid(Sid(unique_restricted_sid));
break; break;
} }
case USER_INTERACTIVE: { case USER_INTERACTIVE: {
...@@ -118,6 +127,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -118,6 +127,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
restricted_token.AddRestrictingSid(WinRestrictedCodeSid); restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
restricted_token.AddRestrictingSidCurrentUser(); restricted_token.AddRestrictingSidCurrentUser();
restricted_token.AddRestrictingSidLogonSession(); restricted_token.AddRestrictingSidLogonSession();
if (unique_restricted_sid)
restricted_token.AddRestrictingSid(Sid(unique_restricted_sid));
break; break;
} }
case USER_LIMITED: { case USER_LIMITED: {
...@@ -128,6 +139,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -128,6 +139,8 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
restricted_token.AddRestrictingSid(WinBuiltinUsersSid); restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
restricted_token.AddRestrictingSid(WinWorldSid); restricted_token.AddRestrictingSid(WinWorldSid);
restricted_token.AddRestrictingSid(WinRestrictedCodeSid); restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
if (unique_restricted_sid)
restricted_token.AddRestrictingSid(Sid(unique_restricted_sid));
// This token has to be able to create objects in BNO. // This token has to be able to create objects in BNO.
// Unfortunately, on Vista+, it needs the current logon sid // Unfortunately, on Vista+, it needs the current logon sid
...@@ -141,11 +154,15 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -141,11 +154,15 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
restricted_token.AddUserSidForDenyOnly(); restricted_token.AddUserSidForDenyOnly();
restricted_token.AddRestrictingSid(WinRestrictedCodeSid); restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
if (unique_restricted_sid)
restricted_token.AddRestrictingSid(Sid(unique_restricted_sid));
break; break;
} }
case USER_LOCKDOWN: { case USER_LOCKDOWN: {
restricted_token.AddUserSidForDenyOnly(); restricted_token.AddUserSidForDenyOnly();
restricted_token.AddRestrictingSid(WinNullSid); restricted_token.AddRestrictingSid(WinNullSid);
if (unique_restricted_sid)
restricted_token.AddRestrictingSid(Sid(unique_restricted_sid));
break; break;
} }
default: { return ERROR_BAD_ARGUMENTS; } default: { return ERROR_BAD_ARGUMENTS; }
......
...@@ -38,6 +38,7 @@ DWORD CreateRestrictedToken(HANDLE effective_token, ...@@ -38,6 +38,7 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
IntegrityLevel integrity_level, IntegrityLevel integrity_level,
TokenType token_type, TokenType token_type,
bool lockdown_default_dacl, bool lockdown_default_dacl,
PSID unique_restricted_sid,
base::win::ScopedHandle* token); base::win::ScopedHandle* token);
// Sets the integrity label on a object handle. // Sets the integrity label on a object handle.
......
...@@ -252,6 +252,10 @@ class TargetPolicy { ...@@ -252,6 +252,10 @@ class TargetPolicy {
// resources. // resources.
virtual void SetLockdownDefaultDacl() = 0; virtual void SetLockdownDefaultDacl() = 0;
// Adds a restricting random SID to the restricted SIDs list as well as
// the default DACL.
virtual void AddRestrictingRandomSid() = 0;
// Enable OPM API redirection when in Win32k lockdown. // Enable OPM API redirection when in Win32k lockdown.
virtual void SetEnableOPMRedirection() = 0; virtual void SetEnableOPMRedirection() = 0;
// Enable OPM API emulation when in Win32k lockdown. // Enable OPM API emulation when in Win32k lockdown.
......
...@@ -109,6 +109,7 @@ PolicyBase::PolicyBase() ...@@ -109,6 +109,7 @@ PolicyBase::PolicyBase()
policy_(nullptr), policy_(nullptr),
lowbox_sid_(nullptr), lowbox_sid_(nullptr),
lockdown_default_dacl_(false), lockdown_default_dacl_(false),
add_restricting_random_sid_(false),
enable_opm_redirection_(false), enable_opm_redirection_(false),
effective_token_(nullptr) { effective_token_(nullptr) {
::InitializeCriticalSection(&lock_); ::InitializeCriticalSection(&lock_);
...@@ -389,6 +390,10 @@ void PolicyBase::SetLockdownDefaultDacl() { ...@@ -389,6 +390,10 @@ void PolicyBase::SetLockdownDefaultDacl() {
lockdown_default_dacl_ = true; lockdown_default_dacl_ = true;
} }
void PolicyBase::AddRestrictingRandomSid() {
add_restricting_random_sid_ = true;
}
const base::HandlesToInheritVector& PolicyBase::GetHandlesBeingShared() { const base::HandlesToInheritVector& PolicyBase::GetHandlesBeingShared() {
return handles_to_share_; return handles_to_share_;
} }
...@@ -413,11 +418,16 @@ ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { ...@@ -413,11 +418,16 @@ ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) {
ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial,
base::win::ScopedHandle* lockdown, base::win::ScopedHandle* lockdown,
base::win::ScopedHandle* lowbox) { base::win::ScopedHandle* lowbox) {
Sid random_sid = Sid::GenerateRandomSid();
PSID random_sid_ptr = nullptr;
if (add_restricting_random_sid_)
random_sid_ptr = random_sid.GetPSID();
// Create the 'naked' token. This will be the permanent token associated // Create the 'naked' token. This will be the permanent token associated
// with the process and therefore with any thread that is not impersonating. // with the process and therefore with any thread that is not impersonating.
DWORD result = DWORD result = CreateRestrictedToken(
CreateRestrictedToken(effective_token_, lockdown_level_, integrity_level_, effective_token_, lockdown_level_, integrity_level_, PRIMARY,
PRIMARY, lockdown_default_dacl_, lockdown); lockdown_default_dacl_, random_sid_ptr, lockdown);
if (ERROR_SUCCESS != result) if (ERROR_SUCCESS != result)
return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_TOKEN; return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_TOKEN;
...@@ -484,9 +494,9 @@ ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, ...@@ -484,9 +494,9 @@ ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial,
// Create the 'better' token. We use this token as the one that the main // Create the 'better' token. We use this token as the one that the main
// thread uses when booting up the process. It should contain most of // thread uses when booting up the process. It should contain most of
// what we need (before reaching main( )) // what we need (before reaching main( ))
result = result = CreateRestrictedToken(
CreateRestrictedToken(effective_token_, initial_level_, integrity_level_, effective_token_, initial_level_, integrity_level_, IMPERSONATION,
IMPERSONATION, lockdown_default_dacl_, initial); lockdown_default_dacl_, random_sid_ptr, initial);
if (ERROR_SUCCESS != result) if (ERROR_SUCCESS != result)
return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_IMP_TOKEN; return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_IMP_TOKEN;
......
...@@ -73,6 +73,7 @@ class PolicyBase final : public TargetPolicy { ...@@ -73,6 +73,7 @@ class PolicyBase final : public TargetPolicy {
const wchar_t* handle_name) override; const wchar_t* handle_name) override;
void AddHandleToShare(HANDLE handle) override; void AddHandleToShare(HANDLE handle) override;
void SetLockdownDefaultDacl() override; void SetLockdownDefaultDacl() override;
void AddRestrictingRandomSid() override;
void SetEnableOPMRedirection() override; void SetEnableOPMRedirection() override;
bool GetEnableOPMRedirection() override; bool GetEnableOPMRedirection() override;
ResultCode AddAppContainerProfile(const wchar_t* package_name, ResultCode AddAppContainerProfile(const wchar_t* package_name,
...@@ -168,6 +169,7 @@ class PolicyBase final : public TargetPolicy { ...@@ -168,6 +169,7 @@ class PolicyBase final : public TargetPolicy {
base::win::ScopedHandle lowbox_directory_; base::win::ScopedHandle lowbox_directory_;
std::unique_ptr<Dispatcher> dispatcher_; std::unique_ptr<Dispatcher> dispatcher_;
bool lockdown_default_dacl_; bool lockdown_default_dacl_;
bool add_restricting_random_sid_;
static HDESK alternate_desktop_handle_; static HDESK alternate_desktop_handle_;
static HWINSTA alternate_winstation_handle_; static HWINSTA alternate_winstation_handle_;
......
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
#include <memory> #include <memory>
#include <sddl.h> #include <sddl.h>
#include <stdlib.h>
#include "base/logging.h" #include "base/logging.h"
#include "base/rand_util.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "sandbox/win/src/win_utils.h" #include "sandbox/win/src/win_utils.h"
...@@ -132,6 +134,14 @@ Sid Sid::AllRestrictedApplicationPackages() { ...@@ -132,6 +134,14 @@ Sid Sid::AllRestrictedApplicationPackages() {
return FromSubAuthorities(&package_authority, 2, sub_authorities); return FromSubAuthorities(&package_authority, 2, sub_authorities);
} }
Sid Sid::GenerateRandomSid() {
SID_IDENTIFIER_AUTHORITY package_authority = {SECURITY_NULL_SID_AUTHORITY};
DWORD sub_authorities[4] = {};
base::RandBytes(&sub_authorities, sizeof(sub_authorities));
return FromSubAuthorities(&package_authority, _countof(sub_authorities),
sub_authorities);
}
PSID Sid::GetPSID() const { PSID Sid::GetPSID() const {
return const_cast<BYTE*>(sid_); return const_cast<BYTE*>(sid_);
} }
......
...@@ -52,6 +52,8 @@ class Sid { ...@@ -52,6 +52,8 @@ class Sid {
PDWORD sub_authorities); PDWORD sub_authorities);
// Create the restricted all application packages sid. // Create the restricted all application packages sid.
static Sid AllRestrictedApplicationPackages(); static Sid AllRestrictedApplicationPackages();
// Generate a random SID value.
static Sid GenerateRandomSid();
// Returns sid_. // Returns sid_.
PSID GetPSID() const; PSID GetPSID() const;
......
...@@ -179,4 +179,12 @@ TEST(SidTest, SubAuthorities) { ...@@ -179,4 +179,12 @@ TEST(SidTest, SubAuthorities) {
ASSERT_TRUE(EqualSid(sid_admin, ATL::Sids::Admins())); ASSERT_TRUE(EqualSid(sid_admin, ATL::Sids::Admins()));
} }
TEST(SidTest, RandomSid) {
Sid sid1 = Sid::GenerateRandomSid();
ASSERT_TRUE(sid1.IsValid());
Sid sid2 = Sid::GenerateRandomSid();
ASSERT_TRUE(sid2.IsValid());
ASSERT_FALSE(::EqualSid(sid1.GetPSID(), sid2.GetPSID()));
}
} // namespace sandbox } // namespace sandbox
...@@ -131,6 +131,7 @@ class TestTargetPolicy : public sandbox::TargetPolicy { ...@@ -131,6 +131,7 @@ class TestTargetPolicy : public sandbox::TargetPolicy {
} }
void AddHandleToShare(HANDLE handle) override {} void AddHandleToShare(HANDLE handle) override {}
void SetLockdownDefaultDacl() override {} void SetLockdownDefaultDacl() override {}
void AddRestrictingRandomSid() override {}
void SetEnableOPMRedirection() override {} void SetEnableOPMRedirection() override {}
bool GetEnableOPMRedirection() override { return false; } bool GetEnableOPMRedirection() override { return false; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment