summaryrefslogtreecommitdiff
path: root/chromium/sandbox
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-20 13:40:20 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-22 12:41:23 +0000
commit7961cea6d1041e3e454dae6a1da660b453efd238 (patch)
treec0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/sandbox
parentb7034d0803538058e5c9d904ef03cf5eab34f6ef (diff)
downloadqtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/sandbox')
-rw-r--r--chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc2
-rw-r--r--chromium/sandbox/linux/syscall_broker/broker_client.cc1
-rw-r--r--chromium/sandbox/linux/syscall_broker/broker_client.h2
-rw-r--r--chromium/sandbox/linux/syscall_broker/broker_process.h8
-rw-r--r--chromium/sandbox/mac/BUILD.gn2
-rw-r--r--chromium/sandbox/mac/mojom/OWNERS4
-rw-r--r--chromium/sandbox/mac/mojom/mojom_traits_unittest.cc (renamed from chromium/sandbox/mac/mojom/struct_traits_unittest.cc)6
-rw-r--r--chromium/sandbox/mac/mojom/seatbelt_extension_token.typemap6
-rw-r--r--chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.cc (renamed from chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.cc)2
-rw-r--r--chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h (renamed from chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h)6
-rw-r--r--chromium/sandbox/win/sandbox_poc/main_ui_window.cc1
-rw-r--r--chromium/sandbox/win/sandbox_poc/sandbox.cc1
-rw-r--r--chromium/sandbox/win/src/app_container_test.cc17
-rw-r--r--chromium/sandbox/win/src/broker_services.cc23
-rw-r--r--chromium/sandbox/win/src/broker_services.h9
-rw-r--r--chromium/sandbox/win/src/process_mitigations.cc47
-rw-r--r--chromium/sandbox/win/src/process_mitigations_unittest.cc24
-rw-r--r--chromium/sandbox/win/src/restricted_token.cc21
-rw-r--r--chromium/sandbox/win/src/restricted_token_test.cc29
-rw-r--r--chromium/sandbox/win/src/restricted_token_utils.cc15
-rw-r--r--chromium/sandbox/win/src/sandbox_policy_base.cc18
-rw-r--r--chromium/sandbox/win/src/security_level.h9
-rw-r--r--chromium/sandbox/win/src/sharedmem_ipc_client.cc2
-rw-r--r--chromium/sandbox/win/src/signed_interception.cc51
-rw-r--r--chromium/sandbox/win/src/win_utils.cc20
-rw-r--r--chromium/sandbox/win/src/win_utils.h7
26 files changed, 232 insertions, 101 deletions
diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
index 7dbcc875229..816c0d63dee 100644
--- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
+++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -313,6 +313,7 @@ bool SyscallSets::IsAllowedSignalHandling(int sysno) {
case __NR_rt_sigaction:
case __NR_rt_sigprocmask:
case __NR_rt_sigreturn:
+ case __NR_rt_sigtimedwait:
#if defined(__i386__) || defined(__arm__) || \
(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
case __NR_sigaction:
@@ -323,7 +324,6 @@ bool SyscallSets::IsAllowedSignalHandling(int sysno) {
case __NR_rt_sigpending:
case __NR_rt_sigqueueinfo:
case __NR_rt_sigsuspend:
- case __NR_rt_sigtimedwait:
case __NR_rt_tgsigqueueinfo:
case __NR_sigaltstack:
#if !defined(__aarch64__)
diff --git a/chromium/sandbox/linux/syscall_broker/broker_client.cc b/chromium/sandbox/linux/syscall_broker/broker_client.cc
index fa7855c2bad..79640d09744 100644
--- a/chromium/sandbox/linux/syscall_broker/broker_client.cc
+++ b/chromium/sandbox/linux/syscall_broker/broker_client.cc
@@ -9,6 +9,7 @@
#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <utility>
diff --git a/chromium/sandbox/linux/syscall_broker/broker_client.h b/chromium/sandbox/linux/syscall_broker/broker_client.h
index a228afec9fd..842ee16a0c7 100644
--- a/chromium/sandbox/linux/syscall_broker/broker_client.h
+++ b/chromium/sandbox/linux/syscall_broker/broker_client.h
@@ -71,7 +71,7 @@ class BrokerClient {
int Stat(const char* pathname, bool follow_links, struct stat* sb) const;
int Stat64(const char* pathname, bool folllow_links, struct stat64* sb) const;
- // Can be used in place of rmdir().
+ // Can be used in place of unlink().
int Unlink(const char* unlink) const;
private:
diff --git a/chromium/sandbox/linux/syscall_broker/broker_process.h b/chromium/sandbox/linux/syscall_broker/broker_process.h
index e994a01d5c1..849238f48e6 100644
--- a/chromium/sandbox/linux/syscall_broker/broker_process.h
+++ b/chromium/sandbox/linux/syscall_broker/broker_process.h
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
-#define SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
+#ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PROCESS_H_
+#define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PROCESS_H_
+
+#include <sys/stat.h>
#include <memory>
#include <string>
@@ -139,4 +141,4 @@ class SANDBOX_EXPORT BrokerProcess {
} // namespace sandbox
-#endif // SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
+#endif // SANDBOX_LINUX_SYSCALL_BROKER_BROKER_PROCESS_H_
diff --git a/chromium/sandbox/mac/BUILD.gn b/chromium/sandbox/mac/BUILD.gn
index cbf9488aa9b..1ef9664ea57 100644
--- a/chromium/sandbox/mac/BUILD.gn
+++ b/chromium/sandbox/mac/BUILD.gn
@@ -67,7 +67,7 @@ component("system_services") {
test("sandbox_mac_unittests") {
sources = [
- "mojom/struct_traits_unittest.cc",
+ "mojom/mojom_traits_unittest.cc",
"sandbox_mac_compiler_unittest.mm",
"sandbox_mac_seatbelt_exec_unittest.cc",
"seatbelt_extension_unittest.cc",
diff --git a/chromium/sandbox/mac/mojom/OWNERS b/chromium/sandbox/mac/mojom/OWNERS
index fc57672d791..3e6cfccf40c 100644
--- a/chromium/sandbox/mac/mojom/OWNERS
+++ b/chromium/sandbox/mac/mojom/OWNERS
@@ -1,6 +1,6 @@
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_mojom_traits*.*=set noparent
+per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS \ No newline at end of file
diff --git a/chromium/sandbox/mac/mojom/struct_traits_unittest.cc b/chromium/sandbox/mac/mojom/mojom_traits_unittest.cc
index ace9c32b3c8..e6f38797d9f 100644
--- a/chromium/sandbox/mac/mojom/struct_traits_unittest.cc
+++ b/chromium/sandbox/mac/mojom/mojom_traits_unittest.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/scoped_task_environment.h"
+#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h"
+#include "sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h"
#include "sandbox/mac/mojom/traits_test_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -29,7 +29,7 @@ class StructTraitsTest : public testing::Test,
std::move(callback).Run(std::move(token));
}
- base::test::ScopedTaskEnvironment task_environment_;
+ base::test::TaskEnvironment task_environment_;
sandbox::mac::mojom::TraitsTestServicePtr interface_ptr_;
mojo::Binding<sandbox::mac::mojom::TraitsTestService> binding_;
diff --git a/chromium/sandbox/mac/mojom/seatbelt_extension_token.typemap b/chromium/sandbox/mac/mojom/seatbelt_extension_token.typemap
index 430faeb78ce..e22e69ce105 100644
--- a/chromium/sandbox/mac/mojom/seatbelt_extension_token.typemap
+++ b/chromium/sandbox/mac/mojom/seatbelt_extension_token.typemap
@@ -5,11 +5,11 @@
mojom = "//sandbox/mac/mojom/seatbelt_extension_token.mojom"
public_headers = [ "//sandbox/mac/seatbelt_extension_token.h" ]
traits_headers =
- [ "//sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h" ]
+ [ "//sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h" ]
sources = [
- "//sandbox/mac/mojom/seatbelt_extension_token_struct_traits.cc",
+ "//sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.cc",
]
deps = [
"//sandbox/mac:seatbelt_extension",
]
-type_mappings = [ "sandbox.mac.mojom.SeatbeltExtensionToken=sandbox::SeatbeltExtensionToken[move_only]" ]
+type_mappings = [ "sandbox.mac.mojom.SeatbeltExtensionToken=::sandbox::SeatbeltExtensionToken[move_only]" ]
diff --git a/chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.cc b/chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.cc
index ae2a1174e8f..fd31c46994c 100644
--- a/chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.cc
+++ b/chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h"
+#include "sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h"
namespace mojo {
diff --git a/chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h b/chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h
index 714802642d7..f9a7bdf1b8a 100644
--- a/chromium/sandbox/mac/mojom/seatbelt_extension_token_struct_traits.h
+++ b/chromium/sandbox/mac/mojom/seatbelt_extension_token_mojom_traits.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_STRUCT_TRAITS_H_
-#define SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_STRUCT_TRAITS_H_
+#ifndef SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_MOJOM_TRAITS_H_
+#define SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_MOJOM_TRAITS_H_
#include <string>
@@ -24,4 +24,4 @@ struct StructTraits<sandbox::mac::mojom::SeatbeltExtensionTokenDataView,
} // namespace mojo
-#endif // SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_STRUCT_TRAITS_H_
+#endif // SANDBOX_MAC_MOJOM_SEATBELT_EXTENSION_TOKEN_MOJOM_TRAITS_H_
diff --git a/chromium/sandbox/win/sandbox_poc/main_ui_window.cc b/chromium/sandbox/win/sandbox_poc/main_ui_window.cc
index 89c1be76697..6bdc171823b 100644
--- a/chromium/sandbox/win/sandbox_poc/main_ui_window.cc
+++ b/chromium/sandbox/win/sandbox_poc/main_ui_window.cc
@@ -626,6 +626,7 @@ void MainUIWindow::AddDebugMessage(const wchar_t* format, ...) {
text[kMaxDebugBuffSize] = L'\0';
InsertLineInListView(text);
+ va_end(arg_list);
}
diff --git a/chromium/sandbox/win/sandbox_poc/sandbox.cc b/chromium/sandbox/win/sandbox_poc/sandbox.cc
index 88757ef6846..6d49a803363 100644
--- a/chromium/sandbox/win/sandbox_poc/sandbox.cc
+++ b/chromium/sandbox/win/sandbox_poc/sandbox.cc
@@ -154,6 +154,7 @@ int APIENTRY _tWinMain(HINSTANCE instance, HINSTANCE, wchar_t* command_line,
HMODULE dll_module = ::LoadLibraryA(dll_name.c_str());
if (dll_module == NULL) {
// TODO(finnur): write the failure to the log file
+ CloseHandle(pipe);
return -5;
}
diff --git a/chromium/sandbox/win/src/app_container_test.cc b/chromium/sandbox/win/src/app_container_test.cc
index d6e3d0e94cb..a6c0948a942 100644
--- a/chromium/sandbox/win/src/app_container_test.cc
+++ b/chromium/sandbox/win/src/app_container_test.cc
@@ -146,6 +146,8 @@ class AppContainerProfileTest : public ::testing::Test {
broker_services_ = GetBroker();
policy_ = broker_services_->CreatePolicy();
ASSERT_EQ(SBOX_ALL_OK,
+ policy_->SetProcessMitigations(MITIGATION_HEAP_TERMINATE));
+ ASSERT_EQ(SBOX_ALL_OK,
policy_->AddAppContainerProfile(package_name_.c_str(), true));
// For testing purposes we known the base class so cast directly.
profile_ = static_cast<AppContainerProfileBase*>(
@@ -212,7 +214,20 @@ TEST_F(AppContainerProfileTest, CheckIncompatibleOptions) {
EXPECT_EQ(SBOX_ERROR_BAD_PARAMS,
policy_->SetIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED));
EXPECT_EQ(SBOX_ERROR_BAD_PARAMS, policy_->SetLowBox(kAppContainerSid));
- EXPECT_EQ(SBOX_ERROR_BAD_PARAMS,
+
+ MitigationFlags expected_mitigations = 0;
+ MitigationFlags expected_delayed = MITIGATION_HEAP_TERMINATE;
+ sandbox::ResultCode expected_result = SBOX_ERROR_BAD_PARAMS;
+
+ if (base::win::GetVersion() >= base::win::Version::WIN10_RS5) {
+ expected_mitigations = MITIGATION_HEAP_TERMINATE;
+ expected_delayed = 0;
+ expected_result = SBOX_ALL_OK;
+ }
+
+ EXPECT_EQ(expected_mitigations, policy_->GetProcessMitigations());
+ EXPECT_EQ(expected_delayed, policy_->GetDelayedProcessMitigations());
+ EXPECT_EQ(expected_result,
policy_->SetProcessMitigations(MITIGATION_HEAP_TERMINATE));
}
diff --git a/chromium/sandbox/win/src/broker_services.cc b/chromium/sandbox/win/src/broker_services.cc
index ae7d15de30e..7c7c53397ba 100644
--- a/chromium/sandbox/win/src/broker_services.cc
+++ b/chromium/sandbox/win/src/broker_services.cc
@@ -282,15 +282,27 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path,
return SBOX_ERROR_BAD_PARAMS;
// Even though the resources touched by SpawnTarget can be accessed in
- // multiple threads, the method itself cannot be called from more than
- // 1 thread. This is to protect the global variables used while setting up
- // the child process.
+ // multiple threads, the method itself cannot be called from more than one
+ // thread. This is to protect the global variables used while setting up the
+ // child process, and to make sure launcher thread mitigations are applied
+ // correctly.
static DWORD thread_id = ::GetCurrentThreadId();
DCHECK(thread_id == ::GetCurrentThreadId());
*last_warning = SBOX_ALL_OK;
AutoLock lock(&lock_);
+ // Launcher thread only needs to be opted out of ACG once. Do this on the
+ // first child process being spawned.
+ static bool launcher_thread_opted_out = false;
+
+ if (!launcher_thread_opted_out) {
+ // Soft fail this call. It will fail if ACG is not enabled for this process.
+ sandbox::ApplyMitigationsToCurrentThread(
+ sandbox::MITIGATION_DYNAMIC_CODE_OPT_OUT_THIS_THREAD);
+ launcher_thread_opted_out = true;
+ }
+
// This downcast is safe as long as we control CreatePolicy()
scoped_refptr<PolicyBase> policy_base(static_cast<PolicyBase*>(policy.get()));
@@ -518,9 +530,4 @@ ResultCode BrokerServicesBase::WaitForAllTargets() {
return SBOX_ALL_OK;
}
-bool BrokerServicesBase::IsActiveTarget(DWORD process_id) {
- AutoLock lock(&lock_);
- return child_process_ids_.find(process_id) != child_process_ids_.end();
-}
-
} // namespace sandbox
diff --git a/chromium/sandbox/win/src/broker_services.h b/chromium/sandbox/win/src/broker_services.h
index 14cfed5f947..701d29a40d1 100644
--- a/chromium/sandbox/win/src/broker_services.h
+++ b/chromium/sandbox/win/src/broker_services.h
@@ -55,12 +55,6 @@ class BrokerServicesBase final : public BrokerServices,
PROCESS_INFORMATION* target) override;
ResultCode WaitForAllTargets() override;
- // Checks if the supplied process ID matches one of the broker's active
- // target processes
- // Returns:
- // true if there is an active target process for this ID, otherwise false.
- bool IsActiveTarget(DWORD process_id);
-
private:
// The routine that the worker thread executes. It is in charge of
// notifications and cleanup-related tasks.
@@ -88,8 +82,7 @@ class BrokerServicesBase final : public BrokerServices,
std::list<std::unique_ptr<JobTracker>> tracker_list_;
// Provides a fast lookup to identify sandboxed processes that belong to a
- // job. Consult |jobless_process_handles_| for handles of processes without
- // jobs.
+ // job.
std::set<DWORD> child_process_ids_;
DISALLOW_COPY_AND_ASSIGN(BrokerServicesBase);
diff --git a/chromium/sandbox/win/src/process_mitigations.cc b/chromium/sandbox/win/src/process_mitigations.cc
index 08a9c894855..e4c6838f96f 100644
--- a/chromium/sandbox/win/src/process_mitigations.cc
+++ b/chromium/sandbox/win/src/process_mitigations.cc
@@ -20,8 +20,6 @@
#include "sandbox/win/src/win_utils.h"
namespace {
-// API defined in winbase.h >= Vista.
-using SetProcessDEPPolicyFunction = decltype(&SetProcessDEPPolicy);
// API defined in libloaderapi.h >= Win8.
using SetDefaultDllDirectoriesFunction = decltype(&SetDefaultDllDirectories);
@@ -145,16 +143,10 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) {
if (flags & MITIGATION_DEP_NO_ATL_THUNK)
dep_flags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION;
- SetProcessDEPPolicyFunction set_process_dep_policy =
- reinterpret_cast<SetProcessDEPPolicyFunction>(
- ::GetProcAddress(module, "SetProcessDEPPolicy"));
- if (set_process_dep_policy) {
- if (!set_process_dep_policy(dep_flags) &&
- ERROR_ACCESS_DENIED != ::GetLastError()) {
- return false;
- }
- } else
+ if (!::SetProcessDEPPolicy(dep_flags) &&
+ ERROR_ACCESS_DENIED != ::GetLastError()) {
return false;
+ }
}
#endif
@@ -225,17 +217,13 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) {
// Enable dynamic code policies.
if (!IsRunning32bitEmulatedOnArm64() &&
- (flags & MITIGATION_DYNAMIC_CODE_DISABLE ||
- flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT)) {
+ (flags & MITIGATION_DYNAMIC_CODE_DISABLE)) {
+ // Verify caller is not accidentally setting both mutually exclusive
+ // policies.
+ DCHECK(!(flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT));
PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy = {};
policy.ProhibitDynamicCode = true;
- // Per-thread opt-out is only supported on >= Anniversary.
- if (version >= base::win::Version::WIN10_RS1 &&
- flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT) {
- policy.AllowThreadOptOut = true;
- }
-
if (!set_process_mitigation_policy(ProcessDynamicCodePolicy, &policy,
sizeof(policy)) &&
ERROR_ACCESS_DENIED != ::GetLastError()) {
@@ -299,6 +287,27 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) {
}
}
+ if (version < base::win::Version::WIN10_RS1)
+ return true;
+
+ // Enable dynamic code policies.
+ // Per-thread opt-out is only supported on >= Anniversary (RS1).
+ if (!IsRunning32bitEmulatedOnArm64() &&
+ (flags & MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT)) {
+ // Verify caller is not accidentally setting both mutually exclusive
+ // policies.
+ DCHECK(!(flags & MITIGATION_DYNAMIC_CODE_DISABLE));
+ PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy = {};
+ policy.ProhibitDynamicCode = true;
+ policy.AllowThreadOptOut = true;
+
+ if (!set_process_mitigation_policy(ProcessDynamicCodePolicy, &policy,
+ sizeof(policy)) &&
+ ERROR_ACCESS_DENIED != ::GetLastError()) {
+ return false;
+ }
+ }
+
return true;
}
diff --git a/chromium/sandbox/win/src/process_mitigations_unittest.cc b/chromium/sandbox/win/src/process_mitigations_unittest.cc
index 2062f39d4ee..81f96451882 100644
--- a/chromium/sandbox/win/src/process_mitigations_unittest.cc
+++ b/chromium/sandbox/win/src/process_mitigations_unittest.cc
@@ -229,7 +229,11 @@ SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) {
return SBOX_TEST_NOT_FOUND;
}
if (!policy.DisallowWin32kSystemCalls)
- return SBOX_TEST_FAILED;
+ return SBOX_TEST_FIRST_ERROR;
+
+ // Check if we can call a Win32k API. Fail if it succeeds.
+ if (::GetDC(nullptr))
+ return SBOX_TEST_SECOND_ERROR;
break;
}
@@ -825,9 +829,23 @@ TEST(ProcessMitigationsTest, CheckWin10MsSigned_Failure) {
false /* add_directory_permission */);
}
+// ASAN doesn't initialize early enough for the intercepts in NtCreateSection to
+// be able to use std::unique_ptr, so disable pre-launch CIG on ASAN builds.
+#if !defined(ADDRESS_SANITIZER)
+#define MAYBE_CheckWin10MsSignedWithIntercept_Success \
+ CheckWin10MsSignedWithIntercept_Success
+#define MAYBE_CheckWin10MsSigned_FailurePreSpawn \
+ CheckWin10MsSigned_FailurePreSpawn
+#else
+#define MAYBE_CheckWin10MsSignedWithIntercept_Success \
+ DISABLED_CheckWin10MsSignedWithIntercept_Success
+#define MAYBE_CheckWin10MsSigned_FailurePreSpawn \
+ DISABLED_CheckWin10MsSigned_FailurePreSpawn
+#endif
+
// This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
// mitigation allows the loading of an unsigned DLL if intercept in place.
-TEST(ProcessMitigationsTest, CheckWin10MsSignedWithIntercept_Success) {
+TEST(ProcessMitigationsTest, MAYBE_CheckWin10MsSignedWithIntercept_Success) {
if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
return;
@@ -854,7 +872,7 @@ TEST(ProcessMitigationsTest, CheckWin10MsSignedWithIntercept_Success) {
// This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
// mitigation pre-load prevents the loading of an unsigned DLL.
-TEST(ProcessMitigationsTest, CheckWin10MsSigned_FailurePreSpawn) {
+TEST(ProcessMitigationsTest, MAYBE_CheckWin10MsSigned_FailurePreSpawn) {
if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
return;
diff --git a/chromium/sandbox/win/src/restricted_token.cc b/chromium/sandbox/win/src/restricted_token.cc
index b68ffd81767..eae0a45e2c2 100644
--- a/chromium/sandbox/win/src/restricted_token.cc
+++ b/chromium/sandbox/win/src/restricted_token.cc
@@ -15,27 +15,14 @@
namespace {
-// Calls GetTokenInformation with the desired |info_class| and returns a buffer
-// with the result.
+// Wrapper for utility version to unwrap ScopedHandle.
std::unique_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token,
TOKEN_INFORMATION_CLASS info_class,
DWORD* error) {
- // Get the required buffer size.
- DWORD size = 0;
- ::GetTokenInformation(token.Get(), info_class, nullptr, 0, &size);
- if (!size) {
- *error = ::GetLastError();
+ std::unique_ptr<BYTE[]> buffer;
+ *error = sandbox::GetTokenInformation(token.Get(), info_class, &buffer);
+ if (*error != ERROR_SUCCESS)
return nullptr;
- }
-
- std::unique_ptr<BYTE[]> buffer(new BYTE[size]);
- if (!::GetTokenInformation(token.Get(), info_class, buffer.get(), size,
- &size)) {
- *error = ::GetLastError();
- return nullptr;
- }
-
- *error = ERROR_SUCCESS;
return buffer;
}
diff --git a/chromium/sandbox/win/src/restricted_token_test.cc b/chromium/sandbox/win/src/restricted_token_test.cc
index a7ba21e47ca..ca7e78f624e 100644
--- a/chromium/sandbox/win/src/restricted_token_test.cc
+++ b/chromium/sandbox/win/src/restricted_token_test.cc
@@ -12,6 +12,7 @@
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/target_services.h"
+#include "sandbox/win/src/win_utils.h"
#include "sandbox/win/tests/common/controller.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -61,6 +62,24 @@ SBOX_TESTS_COMMAND int RestrictedTokenTest_openprocess(int argc,
return SBOX_TEST_DENIED;
}
+// Opens a the process token and checks if it's restricted.
+SBOX_TESTS_COMMAND int RestrictedTokenTest_IsRestricted(int argc,
+ wchar_t** argv) {
+ HANDLE token_handle;
+ if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token_handle))
+ return SBOX_TEST_FIRST_ERROR;
+ base::win::ScopedHandle token(token_handle);
+
+ std::unique_ptr<BYTE[]> groups;
+ if (GetTokenInformation(token_handle, TokenRestrictedSids, &groups) !=
+ ERROR_SUCCESS) {
+ return SBOX_TEST_SECOND_ERROR;
+ }
+
+ auto* token_groups = reinterpret_cast<PTOKEN_GROUPS>(groups.get());
+ return token_groups->GroupCount > 0 ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
+}
+
TEST(RestrictedTokenTest, OpenLowPrivilegedProcess) {
// Test limited privilege to renderer open.
ASSERT_EQ(SBOX_TEST_SUCCEEDED,
@@ -77,4 +96,14 @@ TEST(RestrictedTokenTest, OpenLowPrivilegedProcess) {
RunOpenProcessTest(true, true, PROCESS_ALL_ACCESS));
}
+TEST(RestrictedTokenTest, CheckNonAdminRestricted) {
+ TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_NON_ADMIN);
+ EXPECT_EQ(SBOX_TEST_FAILED,
+ runner.RunTest(L"RestrictedTokenTest_IsRestricted"));
+ TestRunner runner_restricted(JOB_NONE, USER_RESTRICTED_SAME_ACCESS,
+ USER_RESTRICTED_NON_ADMIN);
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED,
+ runner_restricted.RunTest(L"RestrictedTokenTest_IsRestricted"));
+}
+
} // namespace sandbox
diff --git a/chromium/sandbox/win/src/restricted_token_utils.cc b/chromium/sandbox/win/src/restricted_token_utils.cc
index 4717b4ed3d0..53f86e07d87 100644
--- a/chromium/sandbox/win/src/restricted_token_utils.cc
+++ b/chromium/sandbox/win/src/restricted_token_utils.cc
@@ -92,6 +92,21 @@ DWORD CreateRestrictedToken(HANDLE effective_token,
privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
break;
}
+ case USER_RESTRICTED_NON_ADMIN: {
+ sid_exceptions.push_back(WinBuiltinUsersSid);
+ sid_exceptions.push_back(WinWorldSid);
+ sid_exceptions.push_back(WinInteractiveSid);
+ sid_exceptions.push_back(WinAuthenticatedUserSid);
+ privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
+ restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
+ restricted_token.AddRestrictingSid(WinWorldSid);
+ restricted_token.AddRestrictingSid(WinInteractiveSid);
+ restricted_token.AddRestrictingSid(WinAuthenticatedUserSid);
+ restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
+ restricted_token.AddRestrictingSidCurrentUser();
+ restricted_token.AddRestrictingSidLogonSession();
+ break;
+ }
case USER_INTERACTIVE: {
sid_exceptions.push_back(WinBuiltinUsersSid);
sid_exceptions.push_back(WinWorldSid);
diff --git a/chromium/sandbox/win/src/sandbox_policy_base.cc b/chromium/sandbox/win/src/sandbox_policy_base.cc
index a47151d6562..dc4375b3f36 100644
--- a/chromium/sandbox/win/src/sandbox_policy_base.cc
+++ b/chromium/sandbox/win/src/sandbox_policy_base.cc
@@ -305,7 +305,14 @@ ResultCode PolicyBase::SetLowBox(const wchar_t* sid) {
}
ResultCode PolicyBase::SetProcessMitigations(MitigationFlags flags) {
- if (app_container_profile_ || !CanSetProcessMitigationsPreStartup(flags))
+ // Prior to Win10 RS5 CreateProcess fails when AppContainer and mitigation
+ // flags are enabled. Return an error on downlevel platforms if trying to
+ // set new mitigations.
+ if (app_container_profile_ &&
+ base::win::GetVersion() < base::win::Version::WIN10_RS5) {
+ return SBOX_ERROR_BAD_PARAMS;
+ }
+ if (!CanSetProcessMitigationsPreStartup(flags))
return SBOX_ERROR_BAD_PARAMS;
mitigations_ = flags;
return SBOX_ALL_OK;
@@ -626,12 +633,19 @@ ResultCode PolicyBase::AddAppContainerProfile(const wchar_t* package_name,
}
if (!app_container_profile_)
return SBOX_ERROR_CREATE_APPCONTAINER_PROFILE;
+
// A bug exists in CreateProcess where enabling an AppContainer profile and
// passing a set of mitigation flags will generate ERROR_INVALID_PARAMETER.
// Apply best efforts here and convert set mitigations to delayed mitigations.
+ // This bug looks to have been fixed in Win10 RS5, so exit early if possible.
+ if (base::win::GetVersion() >= base::win::Version::WIN10_RS5)
+ return SBOX_ALL_OK;
+
delayed_mitigations_ =
mitigations_ & GetAllowedPostStartupProcessMitigations();
- DCHECK(delayed_mitigations_ == (mitigations_ & ~MITIGATION_SEHOP));
+ DCHECK(delayed_mitigations_ ==
+ (mitigations_ & ~(MITIGATION_SEHOP |
+ MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION)));
mitigations_ = 0;
return SBOX_ALL_OK;
}
diff --git a/chromium/sandbox/win/src/security_level.h b/chromium/sandbox/win/src/security_level.h
index 1036b34a669..8aa3ba8cab2 100644
--- a/chromium/sandbox/win/src/security_level.h
+++ b/chromium/sandbox/win/src/security_level.h
@@ -58,6 +58,14 @@ enum IntegrityLevel {
// | | Authent-users | |
// | | User | |
// ----------------------------|--------------|----------------|----------|
+// USER_RESTRICTED_NON_ADMIN | Users | All except: | Traverse |
+// | Everyone | Users | |
+// | Interactive | Everyone | |
+// | Local | Interactive | |
+// | Authent-users| Local | |
+// | User | Authent-users | |
+// | | User | |
+// ----------------------------|--------------|----------------|----------|
// USER_NON_ADMIN | None | All except: | Traverse |
// | | Users | |
// | | Everyone | |
@@ -86,6 +94,7 @@ enum TokenLevel {
USER_RESTRICTED,
USER_LIMITED,
USER_INTERACTIVE,
+ USER_RESTRICTED_NON_ADMIN,
USER_NON_ADMIN,
USER_RESTRICTED_SAME_ACCESS,
USER_UNPROTECTED,
diff --git a/chromium/sandbox/win/src/sharedmem_ipc_client.cc b/chromium/sandbox/win/src/sharedmem_ipc_client.cc
index 2f849be31a9..3ddea76350b 100644
--- a/chromium/sandbox/win/src/sharedmem_ipc_client.cc
+++ b/chromium/sandbox/win/src/sharedmem_ipc_client.cc
@@ -144,7 +144,7 @@ ResultCode SharedMemIPCClient::DoCall(CrossCallParams* params,
}
// The server has returned an answer, copy it and free the channel.
- memcpy(answer, params->GetCallReturn(), sizeof(CrossCallReturn));
+ memcpy_wrapper(answer, params->GetCallReturn(), sizeof(CrossCallReturn));
// Return the IPC state It can indicate that while the IPC has
// completed some error in the Broker has caused to not return valid
diff --git a/chromium/sandbox/win/src/signed_interception.cc b/chromium/sandbox/win/src/signed_interception.cc
index c0715215487..d9b1bc86b1c 100644
--- a/chromium/sandbox/win/src/signed_interception.cc
+++ b/chromium/sandbox/win/src/signed_interception.cc
@@ -26,45 +26,46 @@ TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
ULONG section_page_protection,
ULONG allocation_attributes,
HANDLE file_handle) {
- NTSTATUS status = orig_CreateSection(
- section_handle, desired_access, object_attributes, maximum_size,
- section_page_protection, allocation_attributes, file_handle);
-
- // Only intercept calls that match a particular signature.
- if (status != STATUS_INVALID_IMAGE_HASH)
- return status;
- if (desired_access != (SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ |
- SECTION_MAP_EXECUTE))
- return status;
- if (object_attributes)
- return status;
- if (maximum_size)
- return status;
- if (section_page_protection != PAGE_EXECUTE)
- return status;
- if (allocation_attributes != SEC_IMAGE)
- return status;
-
do {
- if (!ValidParameter(section_handle, sizeof(HANDLE), WRITE))
+ // The section only needs to have SECTION_MAP_EXECUTE, but the permissions
+ // vary depending on the OS. Windows 1903 and higher requests (SECTION_QUERY
+ // | SECTION_MAP_READ | SECTION_MAP_EXECUTE) while previous OS versions also
+ // request SECTION_MAP_WRITE. Just check for EXECUTE.
+ if (!(desired_access & SECTION_MAP_EXECUTE))
+ break;
+ if (object_attributes)
+ break;
+ if (maximum_size)
+ break;
+ if (section_page_protection != PAGE_EXECUTE)
+ break;
+ if (allocation_attributes != SEC_IMAGE)
break;
+ // IPC must be fully started.
void* memory = GetGlobalIPCMemory();
if (!memory)
break;
+
std::unique_ptr<wchar_t, NtAllocDeleter> path;
+
if (!NtGetPathFromHandle(file_handle, &path))
break;
+
const wchar_t* const_name = path.get();
CountedParameterSet<NameBased> params;
params[NameBased::NAME] = ParamPickerMake(const_name);
+ // Check if this will be sent to the broker.
if (!QueryBroker(IPC_NTCREATESECTION_TAG, params.GetBase()))
break;
+ if (!ValidParameter(section_handle, sizeof(HANDLE), WRITE))
+ break;
+
CrossCallReturn answer = {0};
- answer.nt_status = status;
+ answer.nt_status = STATUS_INVALID_IMAGE_HASH;
SharedMemIPCClient ipc(memory);
ResultCode code =
CrossCall(ipc, IPC_NTCREATESECTION_TAG, file_handle, &answer);
@@ -72,19 +73,21 @@ TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
if (code != SBOX_ALL_OK)
break;
- status = answer.nt_status;
-
if (!NT_SUCCESS(answer.nt_status))
break;
__try {
*section_handle = answer.handle;
+ return answer.nt_status;
} __except (EXCEPTION_EXECUTE_HANDLER) {
break;
}
} while (false);
- return status;
+ // Fall back to the original API in all failure cases.
+ return orig_CreateSection(section_handle, desired_access, object_attributes,
+ maximum_size, section_page_protection,
+ allocation_attributes, file_handle);
}
} // namespace sandbox
diff --git a/chromium/sandbox/win/src/win_utils.cc b/chromium/sandbox/win/src/win_utils.cc
index 2225c88f83e..4b80c6eda77 100644
--- a/chromium/sandbox/win/src/win_utils.cc
+++ b/chromium/sandbox/win/src/win_utils.cc
@@ -545,6 +545,26 @@ void* GetProcessBaseAddress(HANDLE process) {
return base_address;
}
+DWORD GetTokenInformation(HANDLE token,
+ TOKEN_INFORMATION_CLASS info_class,
+ std::unique_ptr<BYTE[]>* buffer) {
+ // Get the required buffer size.
+ DWORD size = 0;
+ ::GetTokenInformation(token, info_class, nullptr, 0, &size);
+ if (!size) {
+ return ::GetLastError();
+ }
+
+ auto temp_buffer = std::make_unique<BYTE[]>(size);
+ if (!::GetTokenInformation(token, info_class, temp_buffer.get(), size,
+ &size)) {
+ return ::GetLastError();
+ }
+
+ *buffer = std::move(temp_buffer);
+ return ERROR_SUCCESS;
+}
+
} // namespace sandbox
void ResolveNTFunctionPtr(const char* name, void* ptr) {
diff --git a/chromium/sandbox/win/src/win_utils.h b/chromium/sandbox/win/src/win_utils.h
index fed7b4c3f35..28ab11b00a8 100644
--- a/chromium/sandbox/win/src/win_utils.h
+++ b/chromium/sandbox/win/src/win_utils.h
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <windows.h>
+#include <memory>
#include <string>
#include "base/macros.h"
@@ -141,6 +142,12 @@ DWORD GetLastErrorFromNtStatus(NTSTATUS status);
// the base address. This should only be called on new, suspended processes.
void* GetProcessBaseAddress(HANDLE process);
+// Calls GetTokenInformation with the desired |info_class| and returns a
+// |buffer| and the Win32 error code.
+DWORD GetTokenInformation(HANDLE token,
+ TOKEN_INFORMATION_CLASS info_class,
+ std::unique_ptr<BYTE[]>* buffer);
+
} // namespace sandbox
// Resolves a function name in NTDLL to a function pointer. The second parameter