diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:20:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:28:57 +0000 |
commit | d17ea114e5ef69ad5d5d7413280a13e6428098aa (patch) | |
tree | 2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/sandbox | |
parent | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff) | |
download | qtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz |
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/sandbox')
21 files changed, 315 insertions, 125 deletions
diff --git a/chromium/sandbox/BUILD.gn b/chromium/sandbox/BUILD.gn index ac5e2c61b8d..c60d5f82229 100644 --- a/chromium/sandbox/BUILD.gn +++ b/chromium/sandbox/BUILD.gn @@ -33,13 +33,16 @@ group("sandbox") { } } -buildflag_header("sandbox_features") { - header = "sandbox_features.h" +buildflag_header("sandbox_buildflags") { + header = "sandbox_buildflags.h" flags = [ "USE_SECCOMP_BPF=$use_seccomp_bpf" ] } # This target must be here and not in win/ otherwise it would require a full # parse of win/BUILD.gn which fails on non-Windows platforms. +# +# Although the code is Windows-based, the fuzzer is designed to work on Linux, +# so do not disable this fuzzer on non-Windows platforms. fuzzer_test("sandbox_ipc_fuzzer") { set_sources_assignment_filter([]) sources = [ diff --git a/chromium/sandbox/OWNERS b/chromium/sandbox/OWNERS index c7304374f32..a52767f0e7f 100644 --- a/chromium/sandbox/OWNERS +++ b/chromium/sandbox/OWNERS @@ -3,6 +3,7 @@ jschuh@chromium.org palmer@chromium.org rsesek@chromium.org tsepez@chromium.org +wfh@chromium.org # TEAM: security-dev@chromium.org # COMPONENT: Internals>Sandbox diff --git a/chromium/sandbox/linux/BUILD.gn b/chromium/sandbox/linux/BUILD.gn index 207ef460ba5..2da57fc9947 100644 --- a/chromium/sandbox/linux/BUILD.gn +++ b/chromium/sandbox/linux/BUILD.gn @@ -289,7 +289,7 @@ if (is_android) { deps = [ "//base", - "//sandbox:sandbox_features", + "//sandbox:sandbox_buildflags", ] if (use_seccomp_bpf) { diff --git a/chromium/sandbox/linux/PRESUBMIT.py b/chromium/sandbox/linux/PRESUBMIT.py index 01059c23fac..0ece8e6aa25 100644 --- a/chromium/sandbox/linux/PRESUBMIT.py +++ b/chromium/sandbox/linux/PRESUBMIT.py @@ -28,7 +28,6 @@ def PostUploadHook(cl, change, output_api): cl, [ 'master.tryserver.chromium.android:android_arm64_dbg_recipe', - 'master.tryserver.chromium.android:android_compile_mips_dbg', 'master.tryserver.chromium.android:android_compile_x64_dbg', 'master.tryserver.chromium.android:android_compile_x86_dbg', ], diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.cc index 2b1294fcdcc..293a6e516b6 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.cc @@ -10,6 +10,7 @@ #include "base/logging.h" #if BUILDFLAG(USE_SECCOMP_BPF) +#include "base/android/build_info.h" #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" #endif @@ -42,7 +43,7 @@ bool SeccompStarterAndroid::StartSandbox() { // apps. It has its own SIGSYS handler that must be un-hooked so that // the Chromium one can be used instead. If pre-O devices have a SIGSYS // handler, then warn about that. - DLOG_IF(WARNING, sdk_int_ < 26) + DLOG_IF(WARNING, sdk_int_ < base::android::SDK_VERSION_OREO) << "Un-hooking existing SIGSYS handler before starting " << "Seccomp sandbox"; } @@ -58,11 +59,11 @@ bool SeccompStarterAndroid::StartSandbox() { bool SeccompStarterAndroid::IsSupportedBySDK() const { #if BUILDFLAG(USE_SECCOMP_BPF) - if (sdk_int_ < 22) { + if (sdk_int_ < base::android::SDK_VERSION_LOLLIPOP_MR1) { // Seccomp was never available pre-Lollipop. return false; } - if (sdk_int_ > 22) { + if (sdk_int_ > base::android::SDK_VERSION_LOLLIPOP_MR1) { // On Marshmallow and higher, Seccomp is required by CTS. return true; } diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.h b/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.h index c5f253ff1f0..8c3f8420a87 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.h +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/seccomp_starter_android.h @@ -6,8 +6,8 @@ #define SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SECCOMP_STARTER_ANDROID_H_ #include "base/macros.h" +#include "sandbox/sandbox_buildflags.h" #include "sandbox/sandbox_export.h" -#include "sandbox/sandbox_features.h" #if BUILDFLAG(USE_SECCOMP_BPF) #include <memory> diff --git a/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc b/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc index 05c783068ae..18e4c14a657 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc @@ -141,12 +141,12 @@ bool BrokerFilePermission::CheckOpen(const char* requested_filename, return false; } - // Check if read is allowed + // Check if read is allowed. if (!allow_read_ && (access_mode == O_RDONLY || access_mode == O_RDWR)) { return false; } - // Check if write is allowed + // Check if write is allowed. if (!allow_write_ && (access_mode == O_WRONLY || access_mode == O_RDWR)) { return false; } @@ -168,6 +168,12 @@ bool BrokerFilePermission::CheckOpen(const char* requested_filename, return false; } + // The effect of (O_RDONLY | O_TRUNC) is undefined, and in some cases it + // actually truncates, so deny. + if (access_mode == O_RDONLY && (flags & O_TRUNC) != 0) { + return false; + } + // Now check that all the flags are known to us. const int creation_and_status_flags = flags & ~O_ACCMODE; const int known_flags = O_APPEND | O_ASYNC | O_CLOEXEC | O_CREAT | O_DIRECT | diff --git a/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc b/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc index 0071016758d..006cc494d56 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc @@ -157,10 +157,21 @@ void CheckPerm(const BrokerFilePermission& perm, case O_NDELAY: #endif case kSyncFlag: - case O_TRUNC: ASSERT_TRUE( perm.CheckOpen(path, access_flags | flag, &file_to_open, NULL)); break; + case O_TRUNC: { + // The effect of (O_RDONLY | O_TRUNC) is undefined, and in some cases it + // actually truncates, so deny. + bool result = + perm.CheckOpen(path, access_flags | flag, &file_to_open, NULL); + if (access_flags == O_RDONLY) { + ASSERT_FALSE(result); + } else { + ASSERT_TRUE(result); + } + break; + } case O_CREAT: continue; // Handled below. case O_CLOEXEC: @@ -197,6 +208,14 @@ TEST(BrokerFilePermission, ReadOnlyRecursive) { // expected. } +// Explicit test for O_RDONLY|O_TRUNC, which should be denied due to +// undefined behavior. +TEST(BrokerFilePermission, ReadOnlyTruncate) { + const char kPath[] = "/tmp/good"; + BrokerFilePermission perm = BrokerFilePermission::ReadOnly(kPath); + ASSERT_FALSE(perm.CheckOpen(kPath, O_RDONLY | O_TRUNC, nullptr, nullptr)); +} + TEST(BrokerFilePermission, WriteOnly) { const char kPath[] = "/tmp/good"; BrokerFilePermission perm = BrokerFilePermission::WriteOnly(kPath); diff --git a/chromium/sandbox/win/fuzzer/fuzzer_types.h b/chromium/sandbox/win/fuzzer/fuzzer_types.h index 0b9dd14dab0..f6a8d7d790e 100644 --- a/chromium/sandbox/win/fuzzer/fuzzer_types.h +++ b/chromium/sandbox/win/fuzzer/fuzzer_types.h @@ -14,7 +14,13 @@ // captured by the fuzzing harness. // Disable exceptions. +#if defined(__try) +#undef __try +#endif #define __try if(true) +#if defined(__except) +#undef __except +#endif #define __except(...) if(false) // Windows types used in sandbox. diff --git a/chromium/sandbox/win/src/broker_services.cc b/chromium/sandbox/win/src/broker_services.cc index c9415c2b388..637ea4fa590 100644 --- a/chromium/sandbox/win/src/broker_services.cc +++ b/chromium/sandbox/win/src/broker_services.cc @@ -318,12 +318,16 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // Initialize the startup information from the policy. base::win::StartupInformation startup_info; + + // We don't want any child processes causing the IDC_APPSTARTING cursor. + startup_info.startup_info()->dwFlags |= STARTF_FORCEOFFFEEDBACK; + // The liftime of |mitigations|, |inherit_handle_list| and // |child_process_creation| have to be at least as long as // |startup_info| because |UpdateProcThreadAttribute| requires that // its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is // called; StartupInformation's destructor makes such a call. - DWORD64 mitigations; + DWORD64 mitigations[2]; std::vector<HANDLE> inherited_handle_list; DWORD child_process_creation = PROCESS_CREATION_CHILD_PROCESS_RESTRICTED; @@ -339,8 +343,8 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, size_t mitigations_size; ConvertProcessMitigationsToPolicy(policy_base->GetProcessMitigations(), - &mitigations, &mitigations_size); - if (mitigations) + &mitigations[0], &mitigations_size); + if (mitigations[0] || mitigations[1]) ++attribute_count; bool restrict_child_process_creation = false; @@ -385,9 +389,9 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, if (!startup_info.InitializeProcThreadAttributeList(attribute_count)) return SBOX_ERROR_PROC_THREAD_ATTRIBUTES; - if (mitigations) { + if (mitigations[0] || mitigations[1]) { if (!startup_info.UpdateProcThreadAttribute( - PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &mitigations, + PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &mitigations[0], mitigations_size)) { return SBOX_ERROR_PROC_THREAD_ATTRIBUTES; } diff --git a/chromium/sandbox/win/src/interception.h b/chromium/sandbox/win/src/interception.h index 057b493929a..1105afbb74f 100644 --- a/chromium/sandbox/win/src/interception.h +++ b/chromium/sandbox/win/src/interception.h @@ -268,10 +268,10 @@ class InterceptionManager { #define MAKE_SERVICE_NAME(service) &Target##service #endif -#define ADD_NT_INTERCEPTION(service, id, num_params) \ - AddToPatchedFunctions(kNtdllName, #service, \ - sandbox::INTERCEPTION_SERVICE_CALL, \ - MAKE_SERVICE_NAME(service), id) +#define ADD_NT_INTERCEPTION(service, id, num_params) \ + AddToPatchedFunctions( \ + kNtdllName, #service, sandbox::INTERCEPTION_SERVICE_CALL, \ + reinterpret_cast<void*>(MAKE_SERVICE_NAME(service)), id) #define INTERCEPT_NT(manager, service, id, num_params) \ manager->ADD_NT_INTERCEPTION(service, id, num_params) @@ -280,9 +280,10 @@ class InterceptionManager { // function not call any functions imported from system libraries unless // |TargetServices::InitCalled()| returns true, because it is only then that // we are guaranteed that our IAT has been initialized. -#define INTERCEPT_EAT(manager, dll, function, id, num_params) \ - manager->AddToPatchedFunctions(dll, #function, sandbox::INTERCEPTION_EAT, \ - MAKE_SERVICE_NAME(function), id) +#define INTERCEPT_EAT(manager, dll, function, id, num_params) \ + manager->AddToPatchedFunctions( \ + dll, #function, sandbox::INTERCEPTION_EAT, \ + reinterpret_cast<void*>(MAKE_SERVICE_NAME(function)), id) #endif // SANDBOX_EXPORTS } // namespace sandbox diff --git a/chromium/sandbox/win/src/process_mitigations.cc b/chromium/sandbox/win/src/process_mitigations.cc index 54c756aece4..e68fe899f59 100644 --- a/chromium/sandbox/win/src/process_mitigations.cc +++ b/chromium/sandbox/win/src/process_mitigations.cc @@ -17,21 +17,54 @@ #include "sandbox/win/src/win_utils.h" namespace { - -// Functions for enabling policies. -typedef BOOL(WINAPI* SetProcessDEPPolicyFunction)(DWORD dwFlags); - -typedef BOOL(WINAPI* SetProcessMitigationPolicyFunction)( - PROCESS_MITIGATION_POLICY mitigation_policy, - PVOID buffer, - SIZE_T length); +// API defined in winbase.h >= Vista. +using SetProcessDEPPolicyFunction = decltype(&SetProcessDEPPolicy); // API defined in libloaderapi.h >= Win8. using SetDefaultDllDirectoriesFunction = decltype(&SetDefaultDllDirectories); -// API defined in processthreadsapi.h >= Win8. +// APIs defined in processthreadsapi.h >= Win8. +using SetProcessMitigationPolicyFunction = + decltype(&SetProcessMitigationPolicy); +using GetProcessMitigationPolicyFunction = + decltype(&GetProcessMitigationPolicy); using SetThreadInformationFunction = decltype(&SetThreadInformation); +// Defines that will eventually be in winbase.h. +// TODO(pennymac): Remove these once the toolchain updates sufficiently. Values +// and formatting match 10.0.17133.0 SDK. +#define PROCESS_CREATION_MITIGATION_POLICY2_RESTRICT_INDIRECT_BRANCH_PREDICTION_ALWAYS_ON \ + (0x00000001ui64 << 16) + +// Returns a two-element array of mitigation flags supported on this machine. +// - This function is only useful on >= base::win::VERSION_WIN8. +const ULONG64* GetSupportedMitigations() { + static ULONG64 mitigations[2] = {}; + + // This static variable will only be initialized once. + if (!mitigations[0] && !mitigations[1]) { + GetProcessMitigationPolicyFunction get_process_mitigation_policy = + reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress( + ::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy")); + if (get_process_mitigation_policy) { + // NOTE: the two-element-sized input array is only supported on >= Win10 + // RS2. + // If an earlier version, the second element will be left 0. + size_t mits_size = + (base::win::GetVersion() >= base::win::VERSION_WIN10_RS2) + ? (sizeof(mitigations[0]) * 2) + : sizeof(mitigations[0]); + if (!get_process_mitigation_policy(::GetCurrentProcess(), + ProcessMitigationOptionsMask, + &mitigations, mits_size)) { + NOTREACHED(); + } + } + } + + return &mitigations[0]; +} + } // namespace namespace sandbox { @@ -274,11 +307,18 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags, size_t* size) { base::win::Version version = base::win::GetVersion(); - *policy_flags = 0; + // |policy_flags| is a two-element array of DWORD64s. Ensure mitigation flags + // from PROCESS_CREATION_MITIGATION_POLICY2_* go into the second value. If + // any flags are set in value 2, update |size| to include both elements. + DWORD64* policy_value_1 = &policy_flags[0]; + DWORD64* policy_value_2 = &policy_flags[1]; + *policy_value_1 = 0; + *policy_value_2 = 0; + #if defined(_WIN64) *size = sizeof(*policy_flags); #elif defined(_M_IX86) - // A 64-bit flags attribute is illegal on 32-bit Win 7 and below. + // A 64-bit flags attribute is illegal on 32-bit Win 7. if (version < base::win::VERSION_WIN8) *size = sizeof(DWORD); else @@ -290,105 +330,149 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags, // DEP and SEHOP are not valid for 64-bit Windows #if !defined(_WIN64) if (flags & MITIGATION_DEP) { - *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE; + *policy_value_1 |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE; if (!(flags & MITIGATION_DEP_NO_ATL_THUNK)) - *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE; + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE; } if (flags & MITIGATION_SEHOP) - *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE; + *policy_value_1 |= PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE; #endif // Win 7 if (version < base::win::VERSION_WIN8) return; - if (flags & MITIGATION_RELOCATE_IMAGE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON; - if (flags & MITIGATION_RELOCATE_IMAGE_REQUIRED) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS; + // Everything >= Win8, do not return before the end of the function where + // the final policy bitmap is sanity checked against what is supported on this + // machine. The API required to do so is only available since Win8. + + // Mitigations >= Win8: + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN8) { + if (flags & MITIGATION_RELOCATE_IMAGE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON; + if (flags & MITIGATION_RELOCATE_IMAGE_REQUIRED) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS; + } } - } - if (flags & MITIGATION_HEAP_TERMINATE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON; - } + if (flags & MITIGATION_HEAP_TERMINATE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_HEAP_TERMINATE_ALWAYS_ON; + } - if (flags & MITIGATION_BOTTOM_UP_ASLR) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON; - } + if (flags & MITIGATION_BOTTOM_UP_ASLR) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_ON; + } - if (flags & MITIGATION_HIGH_ENTROPY_ASLR) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON; - } + if (flags & MITIGATION_HIGH_ENTROPY_ASLR) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_HIGH_ENTROPY_ASLR_ALWAYS_ON; + } - if (flags & MITIGATION_STRICT_HANDLE_CHECKS) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON; - } + if (flags & MITIGATION_STRICT_HANDLE_CHECKS) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON; + } - if (flags & MITIGATION_WIN32K_DISABLE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON; - } + if (flags & MITIGATION_WIN32K_DISABLE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON; + } - if (flags & MITIGATION_EXTENSION_POINT_DISABLE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON; + if (flags & MITIGATION_EXTENSION_POINT_DISABLE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON; + } } - if (version < base::win::VERSION_WIN8_1) - return; + // Mitigations >= Win8.1: + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN8_1) { + if (flags & MITIGATION_DYNAMIC_CODE_DISABLE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON; + } + } - if (flags & MITIGATION_DYNAMIC_CODE_DISABLE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON; + // Mitigations >= Win10: + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN10) { + if (flags & MITIGATION_NONSYSTEM_FONT_DISABLE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_FONT_DISABLE_ALWAYS_ON; + } } - if (version < base::win::VERSION_WIN10) - return; + // Mitigations >= Win10 TH2: + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN10_TH2) { + if (flags & MITIGATION_FORCE_MS_SIGNED_BINS) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; + } - if (flags & MITIGATION_NONSYSTEM_FONT_DISABLE) { - *policy_flags |= PROCESS_CREATION_MITIGATION_POLICY_FONT_DISABLE_ALWAYS_ON; + if (flags & MITIGATION_IMAGE_LOAD_NO_REMOTE) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON; + } + + if (flags & MITIGATION_IMAGE_LOAD_NO_LOW_LABEL) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON; + } } - // Threshold 2 - if (version < base::win::VERSION_WIN10_TH2) - return; + // Mitigations >= Win10 RS1 ("Anniversary"): + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN10_RS1) { + if (flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON_ALLOW_OPT_OUT; + } - if (flags & MITIGATION_FORCE_MS_SIGNED_BINS) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; + if (flags & MITIGATION_IMAGE_LOAD_PREFER_SYS32) { + *policy_value_1 |= + PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON; + } } - if (flags & MITIGATION_IMAGE_LOAD_NO_REMOTE) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON; + // Mitigations >= Win10 RS3 ("Fall Creator's"): + //---------------------------------------------------------------------------- + if (version >= base::win::VERSION_WIN10_RS3) { + // Note: This mitigation requires not only Win10 1709, but also the January + // 2018 security updates and any applicable firmware updates from the + // OEM device manufacturer. + // Note: Applying this mitigation attribute on creation will succeed, even + // if + // the underlying hardware does not support the implementation. + // Windows just does its best under the hood for the given hardware. + if (flags & MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION) { + *policy_value_2 |= + PROCESS_CREATION_MITIGATION_POLICY2_RESTRICT_INDIRECT_BRANCH_PREDICTION_ALWAYS_ON; + } } - if (flags & MITIGATION_IMAGE_LOAD_NO_LOW_LABEL) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON; - } + // When done setting policy flags, sanity check supported policies on this + // machine, and then update |size|. - // Anniversary - if (version < base::win::VERSION_WIN10_RS1) - return; + const ULONG64* supported = GetSupportedMitigations(); - if (flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON_ALLOW_OPT_OUT; - } + *policy_value_1 = *policy_value_1 & supported[0]; + *policy_value_2 = *policy_value_2 & supported[1]; - if (flags & MITIGATION_IMAGE_LOAD_PREFER_SYS32) { - *policy_flags |= - PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON; + // Only include the second element in |size| if it is non-zero. Else, + // UpdateProcThreadAttribute() will return a failure when setting policies. + if (*policy_value_2 && version >= base::win::VERSION_WIN10_RS2) { + *size = sizeof(*policy_flags) * 2; } + + return; } MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags) { @@ -432,15 +516,23 @@ bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process, } MitigationFlags GetAllowedPostStartupProcessMitigations() { - return MITIGATION_HEAP_TERMINATE | MITIGATION_DEP | - MITIGATION_DEP_NO_ATL_THUNK | MITIGATION_RELOCATE_IMAGE | - MITIGATION_RELOCATE_IMAGE_REQUIRED | MITIGATION_BOTTOM_UP_ASLR | - MITIGATION_STRICT_HANDLE_CHECKS | MITIGATION_EXTENSION_POINT_DISABLE | - MITIGATION_DLL_SEARCH_ORDER | MITIGATION_HARDEN_TOKEN_IL_POLICY | - MITIGATION_WIN32K_DISABLE | MITIGATION_DYNAMIC_CODE_DISABLE | + return MITIGATION_HEAP_TERMINATE | + MITIGATION_DEP | + MITIGATION_DEP_NO_ATL_THUNK | + MITIGATION_RELOCATE_IMAGE | + MITIGATION_RELOCATE_IMAGE_REQUIRED | + MITIGATION_BOTTOM_UP_ASLR | + MITIGATION_STRICT_HANDLE_CHECKS | + MITIGATION_EXTENSION_POINT_DISABLE | + MITIGATION_DLL_SEARCH_ORDER | + MITIGATION_HARDEN_TOKEN_IL_POLICY | + MITIGATION_WIN32K_DISABLE | + MITIGATION_DYNAMIC_CODE_DISABLE | MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT | - MITIGATION_FORCE_MS_SIGNED_BINS | MITIGATION_NONSYSTEM_FONT_DISABLE | - MITIGATION_IMAGE_LOAD_NO_REMOTE | MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | + MITIGATION_FORCE_MS_SIGNED_BINS | + MITIGATION_NONSYSTEM_FONT_DISABLE | + MITIGATION_IMAGE_LOAD_NO_REMOTE | + MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | MITIGATION_IMAGE_LOAD_PREFER_SYS32; } diff --git a/chromium/sandbox/win/src/process_mitigations.h b/chromium/sandbox/win/src/process_mitigations.h index cf1844a471a..26dc42e358b 100644 --- a/chromium/sandbox/win/src/process_mitigations.h +++ b/chromium/sandbox/win/src/process_mitigations.h @@ -26,9 +26,10 @@ bool ApplyMitigationsToCurrentThread(MitigationFlags flags); MitigationFlags FilterPostStartupProcessMitigations(MitigationFlags flags); // Converts sandbox flags to the PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES -// policy flags used by UpdateProcThreadAttribute(). The size field varies -// between a 32-bit and a 64-bit type based on the exact build and version of -// Windows, so the returned size must be passed to UpdateProcThreadAttribute(). +// policy flags used by UpdateProcThreadAttribute(). +// - |policy_flags| must be a two-element DWORD64 array. +// - |size| is a size_t so that it can be passed directly into +// UpdateProcThreadAttribute(). void ConvertProcessMitigationsToPolicy(MitigationFlags flags, DWORD64* policy_flags, size_t* size); diff --git a/chromium/sandbox/win/src/process_mitigations_imageload_unittest.cc b/chromium/sandbox/win/src/process_mitigations_imageload_unittest.cc index e5d8ce010f0..ba99dd821d4 100644 --- a/chromium/sandbox/win/src/process_mitigations_imageload_unittest.cc +++ b/chromium/sandbox/win/src/process_mitigations_imageload_unittest.cc @@ -389,13 +389,16 @@ TEST(ProcessMitigationsTest, CheckWin10ImageLoadPreferSys32PolicySuccess) { //--------------------------------- // 1) Test setting pre-startup. + // ** Currently disabled. All PreferSys32 tests start to explode on + // >= Win10 1703/RS2 when this mitigation is set pre-startup. + // Child process creation works fine, but when ::ResumeThread() is called, + // there is a fatal error: "Entry point ucnv_convertEx_60 could not be + // located in the DLL ... sbox_integration_tests.exe." + // This is a character conversion function in a ucnv (unicode) DLL. + // Potentially the loader is finding a different version of this DLL that + // we have a dependency on in System32... but it doesn't match up with + // what we build against???! //--------------------------------- - TestRunner runner; - sandbox::TargetPolicy* policy = runner.GetPolicy(); - - EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_IMAGE_LOAD_PREFER_SYS32), - SBOX_ALL_OK); - EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); //--------------------------------- // 2) Test setting post-startup. diff --git a/chromium/sandbox/win/src/process_mitigations_unittest.cc b/chromium/sandbox/win/src/process_mitigations_unittest.cc index 87dbe9d4a4e..b0b472a1b4e 100644 --- a/chromium/sandbox/win/src/process_mitigations_unittest.cc +++ b/chromium/sandbox/win/src/process_mitigations_unittest.cc @@ -330,6 +330,16 @@ SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) { break; } + //-------------------------------------------------- + // MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION + //-------------------------------------------------- + case (TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION): { + // TODO(pennymac): No Policy defines available yet! + // Can't use GetProcessMitigationPolicy() API to check if enabled at this + // time. If the creation of THIS process succeeded, then the call to + // UpdateProcThreadAttribute() with this mitigation succeeded. + break; + } default: return SBOX_TEST_INVALID_PARAMETER; } @@ -896,4 +906,38 @@ TEST(ProcessMitigationsTest, CheckChildProcessAbnormalExit) { EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); } +//------------------------------------------------------------------------------ +// Restrict indirect branch prediction +// (MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION) +// >= Win10 RS3 +//------------------------------------------------------------------------------ + +// This test validates that setting the +// MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION mitigation enables the setting +// on a process. +TEST(ProcessMitigationsTest, + CheckWin10RestrictIndirectBranchPredictionPolicySuccess) { + if (base::win::GetVersion() < base::win::VERSION_WIN10_RS3) + return; + + base::string16 test_command = L"CheckPolicy "; + test_command += std::to_wstring(TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION); + + //--------------------------------- + // 1) Test setting pre-startup. + //--------------------------------- + TestRunner runner; + sandbox::TargetPolicy* policy = runner.GetPolicy(); + + EXPECT_EQ(policy->SetProcessMitigations( + MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION), + SBOX_ALL_OK); + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); + + //--------------------------------- + // 2) Test setting post-startup. + // ** Post-startup not supported. Must be enabled on creation. + //--------------------------------- +} + } // namespace sandbox diff --git a/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc b/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc index 81be0edba4d..70247ae1d74 100644 --- a/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc +++ b/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc @@ -280,9 +280,9 @@ bool WINAPI GetMonitorInfoWTest(HMONITOR monitor, LPMONITORINFO monitor_info) { return true; } -#define RETURN_TEST_FUNC(n) \ - if (strcmp(name, #n) == 0) { \ - return n##Test; \ +#define RETURN_TEST_FUNC(n) \ + if (strcmp(name, #n) == 0) { \ + return reinterpret_cast<void*>(n##Test); \ } void* FunctionOverrideForTest(const char* name) { diff --git a/chromium/sandbox/win/src/resolver.cc b/chromium/sandbox/win/src/resolver.cc index 2f0fbc0e942..6ed20e9b511 100644 --- a/chromium/sandbox/win/src/resolver.cc +++ b/chromium/sandbox/win/src/resolver.cc @@ -52,7 +52,7 @@ NTSTATUS ResolverThunk::ResolveInterceptor(const void* interceptor_module, if (!pe.VerifyMagic()) return STATUS_INVALID_IMAGE_FORMAT; - *address = pe.GetProcAddress(interceptor_name); + *address = reinterpret_cast<void*>(pe.GetProcAddress(interceptor_name)); if (!(*address)) return STATUS_PROCEDURE_NOT_FOUND; diff --git a/chromium/sandbox/win/src/security_level.h b/chromium/sandbox/win/src/security_level.h index c9b8a7df4f5..b672aad76ba 100644 --- a/chromium/sandbox/win/src/security_level.h +++ b/chromium/sandbox/win/src/security_level.h @@ -255,6 +255,12 @@ const MitigationFlags MITIGATION_IMAGE_LOAD_NO_LOW_LABEL = 0x00080000; // PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_PREFER_SYSTEM32_ALWAYS_ON. const MitigationFlags MITIGATION_IMAGE_LOAD_PREFER_SYS32 = 0x00100000; +// Prevents hyperthreads from interfering with indirect branch predictions. +// (SPECTRE Variant 2 mitigation.) Corresponds to +// PROCESS_CREATION_MITIGATION_POLICY2_RESTRICT_INDIRECT_BRANCH_PREDICTION_ALWAYS_ON. +const MitigationFlags MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION = + 0x00200000; + } // namespace sandbox #endif // SANDBOX_SRC_SECURITY_LEVEL_H_ diff --git a/chromium/sandbox/win/src/service_resolver.cc b/chromium/sandbox/win/src/service_resolver.cc index 42a73b87e39..f26322dd634 100644 --- a/chromium/sandbox/win/src/service_resolver.cc +++ b/chromium/sandbox/win/src/service_resolver.cc @@ -29,7 +29,8 @@ NTSTATUS ServiceResolverThunk::ResolveTarget(const void* module, return STATUS_UNSUCCESSFUL; base::win::PEImage module_image(module); - *address = module_image.GetProcAddress(function_name); + *address = + reinterpret_cast<void*>(module_image.GetProcAddress(function_name)); if (!*address) { NOTREACHED_NT(); diff --git a/chromium/sandbox/win/src/service_resolver_unittest.cc b/chromium/sandbox/win/src/service_resolver_unittest.cc index 30b13c4a5ef..f5375c5bf01 100644 --- a/chromium/sandbox/win/src/service_resolver_unittest.cc +++ b/chromium/sandbox/win/src/service_resolver_unittest.cc @@ -107,7 +107,8 @@ NTSTATUS PatchNtdllWithResolver(const char* function, HMODULE ntdll_base = ::GetModuleHandle(L"ntdll.dll"); EXPECT_TRUE(ntdll_base); - void* target = ::GetProcAddress(ntdll_base, function); + void* target = + reinterpret_cast<void*>(::GetProcAddress(ntdll_base, function)); EXPECT_TRUE(target); if (!target) return STATUS_UNSUCCESSFUL; @@ -245,7 +246,8 @@ TEST(ServiceResolverTest, LocalPatchesAllowed) { const char kFunctionName[] = "NtClose"; - void* target = ::GetProcAddress(ntdll_base, kFunctionName); + void* target = + reinterpret_cast<void*>(::GetProcAddress(ntdll_base, kFunctionName)); ASSERT_TRUE(target); BYTE service[50]; diff --git a/chromium/sandbox/win/src/sidestep_resolver.cc b/chromium/sandbox/win/src/sidestep_resolver.cc index a2045f9c32b..59274893b8e 100644 --- a/chromium/sandbox/win/src/sidestep_resolver.cc +++ b/chromium/sandbox/win/src/sidestep_resolver.cc @@ -108,14 +108,15 @@ NTSTATUS SmartSidestepResolverThunk::Setup(const void* target_module, // to our internal smart interceptor. size_t standard_bytes = storage_bytes - offsetof(SmartThunk, sidestep); ret = SidestepResolverThunk::Setup(target_module, interceptor_module, - target_name, nullptr, &SmartStub, + target_name, nullptr, + reinterpret_cast<void*>(&SmartStub), &thunk->sidestep, standard_bytes, nullptr); if (!NT_SUCCESS(ret)) return ret; // Fix the internal thunk to pass the whole buffer to the interceptor. SetInternalThunk(&thunk->sidestep.internal_thunk, GetInternalThunkSize(), - thunk_storage, &SmartStub); + thunk_storage, reinterpret_cast<void*>(&SmartStub)); if (storage_used) *storage_used = GetThunkSize(); |