diff options
author | forshaw <forshaw@chromium.org> | 2015-01-26 11:27:25 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-26 19:28:43 +0000 |
commit | 19669894e93f9279e860d9fff6a54f6cd042acd7 (patch) | |
tree | 5899ee8aec9b41e4b88019b65b6190194a4c130a /sandbox | |
parent | 58ee32e05d510fff9190c5f05fc9b0ea0df31ac1 (diff) | |
download | chromium_src-19669894e93f9279e860d9fff6a54f6cd042acd7.zip chromium_src-19669894e93f9279e860d9fff6a54f6cd042acd7.tar.gz chromium_src-19669894e93f9279e860d9fff6a54f6cd042acd7.tar.bz2 |
Added a new process mitigation to harden process token IL policy.
This adds a new process mitigation policy to harden the current process
token's integrity level policy. What this actually means is the token's
IL policy in its SACL is modified to add no-read-up and no-execute-up
which is not the default. This prevents a lower privilege process from
opening the token object with rights such as duplicate and impersonation
which could be used to circumvent sandbox restrictions and elevate
privileges. While the policy is only enabled on the browser process by
making it a general mitigation policy it could be applied to all process
levels such as the GPU process to provide a similar effect.
BUG=440692
Review URL: https://codereview.chromium.org/810083002
Cr-Commit-Position: refs/heads/master@{#313099}
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/win/src/process_mitigations.cc | 11 | ||||
-rw-r--r-- | sandbox/win/src/restricted_token_utils.cc | 63 | ||||
-rw-r--r-- | sandbox/win/src/restricted_token_utils.h | 13 | ||||
-rw-r--r-- | sandbox/win/src/security_level.h | 5 |
4 files changed, 91 insertions, 1 deletions
diff --git a/sandbox/win/src/process_mitigations.cc b/sandbox/win/src/process_mitigations.cc index 80e4284..d187c55 100644 --- a/sandbox/win/src/process_mitigations.cc +++ b/sandbox/win/src/process_mitigations.cc @@ -8,6 +8,7 @@ #include "base/win/windows_version.h" #include "sandbox/win/src/nt_internals.h" +#include "sandbox/win/src/restricted_token_utils.h" #include "sandbox/win/src/win_utils.h" namespace { @@ -59,6 +60,13 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) { } } + if (version >= base::win::VERSION_WIN7 && + (flags & MITIGATION_HARDEN_TOKEN_IL_POLICY)) { + DWORD error = HardenProcessIntegrityLevelPolicy(); + if ((error != ERROR_SUCCESS) && (error != ERROR_ACCESS_DENIED)) + return false; + } + #if !defined(_WIN64) // DEP is always enabled on 64-bit. if (flags & MITIGATION_DEP) { DWORD dep_flags = PROCESS_DEP_ENABLE; @@ -309,7 +317,8 @@ bool CanSetProcessMitigationsPostStartup(MitigationFlags flags) { MITIGATION_BOTTOM_UP_ASLR | MITIGATION_STRICT_HANDLE_CHECKS | MITIGATION_EXTENSION_DLL_DISABLE | - MITIGATION_DLL_SEARCH_ORDER)); + MITIGATION_DLL_SEARCH_ORDER | + MITIGATION_HARDEN_TOKEN_IL_POLICY)); } bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) { diff --git a/sandbox/win/src/restricted_token_utils.cc b/sandbox/win/src/restricted_token_utils.cc index 93b212e..5e06daa 100644 --- a/sandbox/win/src/restricted_token_utils.cc +++ b/sandbox/win/src/restricted_token_utils.cc @@ -342,4 +342,67 @@ DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) { return SetTokenIntegrityLevel(token.Get(), integrity_level); } +DWORD HardenTokenIntegrityLevelPolicy(HANDLE token) { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return ERROR_SUCCESS; + + DWORD last_error = 0; + DWORD length_needed = 0; + + ::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, + NULL, 0, &length_needed); + + last_error = ::GetLastError(); + if (last_error != ERROR_INSUFFICIENT_BUFFER) + return last_error; + + std::vector<char> security_desc_buffer(length_needed); + PSECURITY_DESCRIPTOR security_desc = + reinterpret_cast<PSECURITY_DESCRIPTOR>(&security_desc_buffer[0]); + + if (!::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, + security_desc, length_needed, + &length_needed)) + return ::GetLastError(); + + PACL sacl = NULL; + BOOL sacl_present = FALSE; + BOOL sacl_defaulted = FALSE; + + if (!::GetSecurityDescriptorSacl(security_desc, &sacl_present, + &sacl, &sacl_defaulted)) + return ::GetLastError(); + + for (DWORD ace_index = 0; ace_index < sacl->AceCount; ++ace_index) { + PSYSTEM_MANDATORY_LABEL_ACE ace; + + if (::GetAce(sacl, ace_index, reinterpret_cast<LPVOID*>(&ace)) + && ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) { + ace->Mask |= SYSTEM_MANDATORY_LABEL_NO_READ_UP + | SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP; + break; + } + } + + if (!::SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, + security_desc)) + return ::GetLastError(); + + return ERROR_SUCCESS; +} + +DWORD HardenProcessIntegrityLevelPolicy() { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return ERROR_SUCCESS; + + HANDLE token_handle; + if (!::OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, + &token_handle)) + return ::GetLastError(); + + base::win::ScopedHandle token(token_handle); + + return HardenTokenIntegrityLevelPolicy(token.Get()); +} + } // namespace sandbox diff --git a/sandbox/win/src/restricted_token_utils.h b/sandbox/win/src/restricted_token_utils.h index 69462b4..509feaf 100644 --- a/sandbox/win/src/restricted_token_utils.h +++ b/sandbox/win/src/restricted_token_utils.h @@ -82,6 +82,19 @@ const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level); // current integrity level, the function will fail. DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level); +// Hardens the integrity level policy on a token. This is only valid on Win 7 +// and above. Specifically it sets the policy to block read and execute so +// that a lower privileged process cannot open the token for impersonate or +// duplicate permissions. This should limit potential security holes. +DWORD HardenTokenIntegrityLevelPolicy(HANDLE token); + +// Hardens the integrity level policy on the current process. This is only +// valid on Win 7 and above. Specifically it sets the policy to block read +// and execute so that a lower privileged process cannot open the token for +// impersonate or duplicate permissions. This should limit potential security +// holes. +DWORD HardenProcessIntegrityLevelPolicy(); + } // namespace sandbox #endif // SANDBOX_SRC_RESTRICTED_TOKEN_UTILS_H__ diff --git a/sandbox/win/src/security_level.h b/sandbox/win/src/security_level.h index da84b752..c89bbb4 100644 --- a/sandbox/win/src/security_level.h +++ b/sandbox/win/src/security_level.h @@ -199,6 +199,11 @@ const MitigationFlags MITIGATION_EXTENSION_DLL_DISABLE = 0x00000400; // Must be enabled after startup. const MitigationFlags MITIGATION_DLL_SEARCH_ORDER = 0x00000001ULL << 32; +// Changes the mandatory integrity level policy on the current process' token +// to enable no-read and no-execute up. This prevents a lower IL process from +// opening the process token for impersonate/duplicate/assignment. +const MitigationFlags MITIGATION_HARDEN_TOKEN_IL_POLICY = 0x00000001ULL << 33; + } // namespace sandbox #endif // SANDBOX_SRC_SECURITY_LEVEL_H_ |