diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-03 13:42:47 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:27:51 +0000 |
commit | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (patch) | |
tree | d29d987c4d7b173cf853279b79a51598f104b403 /chromium/sandbox | |
parent | 830c9e163d31a9180fadca926b3e1d7dfffb5021 (diff) | |
download | qtwebengine-chromium-8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec.tar.gz |
BASELINE: Update Chromium to 66.0.3359.156
Change-Id: I0c9831ad39911a086b6377b16f995ad75a51e441
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/sandbox')
50 files changed, 944 insertions, 280 deletions
diff --git a/chromium/sandbox/linux/BUILD.gn b/chromium/sandbox/linux/BUILD.gn index 9d4726f89e4..207ef460ba5 100644 --- a/chromium/sandbox/linux/BUILD.gn +++ b/chromium/sandbox/linux/BUILD.gn @@ -37,7 +37,6 @@ group("sandbox") { public_deps = [ ":sandbox_services", ] - if (compile_suid_client || is_nacl_nonsfi) { public_deps += [ ":suid_sandbox_client" ] } @@ -150,6 +149,10 @@ source_set("sandbox_linux_unittests_sources") { "seccomp-bpf/trap_unittest.cc", ] deps += [ ":bpf_dsl_golden" ] + + if (is_android) { + sources += [ "seccomp-bpf-helpers/baseline_policy_android_unittest.cc" ] + } } if (compile_credentials) { sources += [ @@ -418,6 +421,11 @@ component("sandbox_services") { "syscall_broker/broker_process.cc", "syscall_broker/broker_process.h", ] + } else if (!is_android) { + sources += [ + "services/libc_interceptor.cc", + "services/libc_interceptor.h", + ] } } diff --git a/chromium/sandbox/linux/bpf_dsl/dump_bpf.h b/chromium/sandbox/linux/bpf_dsl/dump_bpf.h index a7db58981bf..34f1aa99f2b 100644 --- a/chromium/sandbox/linux/bpf_dsl/dump_bpf.h +++ b/chromium/sandbox/linux/bpf_dsl/dump_bpf.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_LINUX_BPF_DSL_DUMP_BPF_H_ +#define SANDBOX_LINUX_BPF_DSL_DUMP_BPF_H_ + #include <string> #include "sandbox/linux/bpf_dsl/codegen.h" @@ -22,3 +25,5 @@ class SANDBOX_EXPORT DumpBPF { } // namespace bpf_dsl } // namespace sandbox + +#endif // SANDBOX_LINUX_BPF_DSL_DUMP_BPF_H_ diff --git a/chromium/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc b/chromium/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc index 2fa12b36aaa..a984de1a781 100644 --- a/chromium/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc +++ b/chromium/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc @@ -774,6 +774,7 @@ ResultExpr SimpleCondTestPolicy::EvaluateSyscall(int sysno) const { #if defined(__NR_open) case __NR_open: flags_argument_position = 1; + FALLTHROUGH; #endif case __NR_openat: { // open can be a wrapper for openat(2). if (sysno == __NR_openat) diff --git a/chromium/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc b/chromium/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc index b1990041425..6840dba8616 100644 --- a/chromium/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc +++ b/chromium/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc @@ -12,6 +12,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback.h" #include "base/macros.h" #include "base/posix/eintr_wrapper.h" #include "build/build_config.h" @@ -35,10 +36,6 @@ using bpf_dsl::Allow; using bpf_dsl::ResultExpr; using bpf_dsl::Trap; -bool NoOpCallback() { - return true; -} - // Test a trap handler that makes use of a broker process to open(). class InitializedOpenBroker { @@ -52,7 +49,7 @@ class InitializedOpenBroker { syscall_broker::BrokerFilePermission::ReadOnly("/proc/cpuinfo")}; broker_process_ = std::make_unique<syscall_broker::BrokerProcess>( EPERM, command_set, permissions); - BPF_ASSERT(broker_process_->Init(base::Bind(&NoOpCallback))); + BPF_ASSERT(broker_process_->Init(base::Bind([]() { return true; }))); initialized_ = true; } diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc index 6aab37a88f4..46a54ed1233 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc @@ -213,7 +213,8 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno, } #endif - // crbug.com/701137 + // On Android, for https://crbug.com/701137. + // On Desktop, for https://crbug.com/741984. if (sysno == __NR_mincore) { return Allow(); } diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc index 9a37225780b..f0b658d4b63 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc @@ -170,6 +170,11 @@ ResultExpr BaselinePolicyAndroid::EvaluateSyscall(int sysno) const { return RestrictClockID(); } + // https://crbug.com/826289 + if (sysno == __NR_getrusage) { + return RestrictGetrusage(); + } + #if defined(__x86_64__) if (sysno == __NR_arch_prctl) { const Arg<int> code(0); diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android_unittest.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android_unittest.cc new file mode 100644 index 00000000000..ceecbaf76b0 --- /dev/null +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android_unittest.cc @@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.h" + +#include <sys/resource.h> + +#include "sandbox/linux/seccomp-bpf/bpf_tests.h" + +namespace sandbox { +namespace { + +BPF_TEST_C(BaselinePolicyAndroid, Getrusage, BaselinePolicyAndroid) { + struct rusage usage{}; + + errno = 0; + BPF_ASSERT_EQ(0, getrusage(RUSAGE_SELF, &usage)); + + errno = 0; + BPF_ASSERT_EQ(0, getrusage(RUSAGE_THREAD, &usage)); +} + +} // namespace +} // namespace sandbox diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc index ada0b8f23ae..2577f02f2e9 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc @@ -334,7 +334,8 @@ ResultExpr RestrictPrlimit64(pid_t target_pid) { ResultExpr RestrictGetrusage() { const Arg<int> who(0); - return If(who == RUSAGE_SELF, Allow()).Else(CrashSIGSYS()); + return If(AnyOf(who == RUSAGE_SELF, who == RUSAGE_THREAD), Allow()) + .Else(CrashSIGSYS()); } #endif // !defined(OS_NACL_NONSFI) diff --git a/chromium/sandbox/linux/services/credentials.cc b/chromium/sandbox/linux/services/credentials.cc index 65b63adfe2f..ad0714a7f5e 100644 --- a/chromium/sandbox/linux/services/credentials.cc +++ b/chromium/sandbox/linux/services/credentials.cc @@ -6,6 +6,7 @@ #include <errno.h> #include <limits.h> +#include <sched.h> #include <signal.h> #include <stddef.h> #include <stdint.h> diff --git a/chromium/sandbox/linux/services/init_process_reaper.cc b/chromium/sandbox/linux/services/init_process_reaper.cc index 2ff18b5dc28..112fa0a321d 100644 --- a/chromium/sandbox/linux/services/init_process_reaper.cc +++ b/chromium/sandbox/linux/services/init_process_reaper.cc @@ -23,7 +23,7 @@ void DoNothingSignalHandler(int signal) {} } // namespace -bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) { +bool CreateInitProcessReaper(base::OnceClosure post_fork_parent_callback) { int sync_fds[2]; // We want to use send, so we can't use a pipe if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_fds)) { @@ -54,8 +54,9 @@ bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) { DPCHECK(!close_ret); close_ret = shutdown(sync_fds[1], SHUT_RD); DPCHECK(!close_ret); - if (post_fork_parent_callback) - post_fork_parent_callback->Run(); + if (!post_fork_parent_callback.is_null()) + std::move(post_fork_parent_callback).Run(); + // Tell the child to continue CHECK(HANDLE_EINTR(send(sync_fds[1], "C", 1, MSG_NOSIGNAL)) == 1); close_ret = IGNORE_EINTR(close(sync_fds[1])); diff --git a/chromium/sandbox/linux/services/init_process_reaper.h b/chromium/sandbox/linux/services/init_process_reaper.h index 840f6fcda7b..a5dbaec79ce 100644 --- a/chromium/sandbox/linux/services/init_process_reaper.h +++ b/chromium/sandbox/linux/services/init_process_reaper.h @@ -12,13 +12,11 @@ namespace sandbox { // The current process will fork(). The parent will become a process reaper // like init(1). The child will continue normally (after this function -// returns). -// If not NULL, |post_fork_parent_callback| will run in the parent almost -// immediately after fork(). -// Since this function calls fork(), it's very important that the caller has -// only one thread running. +// returns). If not empty, |post_fork_parent_callback| will run in the parent +// almost immediately after fork(). Since this function calls fork(), it's very +// important that the caller has only one thread running. SANDBOX_EXPORT bool CreateInitProcessReaper( - base::Closure* post_fork_parent_callback); + base::OnceClosure post_fork_parent_callback); } // namespace sandbox. diff --git a/chromium/sandbox/linux/services/libc_interceptor.cc b/chromium/sandbox/linux/services/libc_interceptor.cc new file mode 100644 index 00000000000..906e1caf8ac --- /dev/null +++ b/chromium/sandbox/linux/services/libc_interceptor.cc @@ -0,0 +1,353 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sandbox/linux/services/libc_interceptor.h" + +#include <dlfcn.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#include <sys/prctl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#include <set> +#include <string> + +#include "base/lazy_instance.h" +#include "base/memory/protected_memory.h" +#include "base/memory/protected_memory_cfi.h" +#include "base/pickle.h" +#include "base/posix/eintr_wrapper.h" +#include "base/posix/global_descriptors.h" +#include "base/posix/unix_domain_socket.h" +#include "base/synchronization/lock.h" + +namespace sandbox { + +namespace { + +// The global |g_am_zygote_or_renderer| is true iff we are in a zygote or +// renderer process. It's set in ZygoteMain and inherited by the renderers when +// they fork. (This means that it'll be incorrect for global constructor +// functions and before ZygoteMain is called - beware). +bool g_am_zygote_or_renderer = false; +bool g_use_localtime_override = true; +int g_backchannel_fd = -1; + +base::LazyInstance<std::set<std::string>>::Leaky g_timezones = + LAZY_INSTANCE_INITIALIZER; + +base::LazyInstance<base::Lock>::Leaky g_timezones_lock = + LAZY_INSTANCE_INITIALIZER; + +bool ReadTimeStruct(base::PickleIterator* iter, + struct tm* output, + char* timezone_out, + size_t timezone_out_len) { + int result; + if (!iter->ReadInt(&result)) + return false; + output->tm_sec = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_min = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_hour = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_mday = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_mon = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_year = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_wday = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_yday = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_isdst = result; + if (!iter->ReadInt(&result)) + return false; + output->tm_gmtoff = result; + + std::string timezone; + if (!iter->ReadString(&timezone)) + return false; + if (timezone_out_len) { + const size_t copy_len = std::min(timezone_out_len - 1, timezone.size()); + memcpy(timezone_out, timezone.data(), copy_len); + timezone_out[copy_len] = 0; + output->tm_zone = timezone_out; + } else { + base::AutoLock lock(g_timezones_lock.Get()); + auto ret_pair = g_timezones.Get().insert(timezone); + output->tm_zone = ret_pair.first->c_str(); + } + + return true; +} + +void WriteTimeStruct(base::Pickle* pickle, const struct tm* time) { + pickle->WriteInt(time->tm_sec); + pickle->WriteInt(time->tm_min); + pickle->WriteInt(time->tm_hour); + pickle->WriteInt(time->tm_mday); + pickle->WriteInt(time->tm_mon); + pickle->WriteInt(time->tm_year); + pickle->WriteInt(time->tm_wday); + pickle->WriteInt(time->tm_yday); + pickle->WriteInt(time->tm_isdst); + pickle->WriteInt(time->tm_gmtoff); + pickle->WriteString(time->tm_zone); +} + +// See +// https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md +void ProxyLocaltimeCallToBrowser(time_t input, + struct tm* output, + char* timezone_out, + size_t timezone_out_len) { + base::Pickle request; + request.WriteInt(METHOD_LOCALTIME); + request.WriteString( + std::string(reinterpret_cast<char*>(&input), sizeof(input))); + + memset(output, 0, sizeof(struct tm)); + + uint8_t reply_buf[512]; + const ssize_t r = base::UnixDomainSocket::SendRecvMsg( + g_backchannel_fd, reply_buf, sizeof(reply_buf), nullptr, request); + if (r == -1) + return; + + base::Pickle reply(reinterpret_cast<char*>(reply_buf), r); + base::PickleIterator iter(reply); + if (!ReadTimeStruct(&iter, output, timezone_out, timezone_out_len)) { + memset(output, 0, sizeof(struct tm)); + } +} + +// The other side of this call is ProxyLocaltimeCallToBrowser(). +bool HandleLocalTime(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + std::string time_string; + if (!iter.ReadString(&time_string) || time_string.size() != sizeof(time_t)) + return false; + + time_t time; + memcpy(&time, time_string.data(), sizeof(time)); + // We use |localtime| here because we need the |tm_zone| field to be filled + // out. Since we are a single-threaded process, this is safe. + const struct tm* expanded_time = localtime(&time); + + base::Pickle reply; + if (expanded_time) { + WriteTimeStruct(&reply, expanded_time); + } else { + // The {} constructor ensures the struct is 0-initialized. + struct tm zeroed_time = {}; + WriteTimeStruct(&reply, &zeroed_time); + } + + struct msghdr msg; + memset(&msg, 0, sizeof(msg)); + + struct iovec iov = {const_cast<void*>(reply.data()), reply.size()}; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + if (HANDLE_EINTR(sendmsg(fds[0].get(), &msg, MSG_DONTWAIT)) < 0) + PLOG(ERROR) << "sendmsg"; + + return true; +} + +} // namespace + +typedef struct tm* (*LocaltimeFunction)(const time_t* timep); +typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, + struct tm* result); +struct LibcFunctions { + LocaltimeFunction localtime; + LocaltimeFunction localtime64; + LocaltimeRFunction localtime_r; + LocaltimeRFunction localtime64_r; +}; + +static pthread_once_t g_libc_funcs_guard = PTHREAD_ONCE_INIT; +// The libc function pointers are stored in read-only memory after being +// dynamically resolved as a security mitigation to prevent the pointer from +// being tampered with. See https://crbug.com/771365 for details. +static PROTECTED_MEMORY_SECTION base::ProtectedMemory<LibcFunctions> + g_libc_funcs; + +static void InitLibcLocaltimeFunctions() { + auto writer = base::AutoWritableMemory::Create(g_libc_funcs); + g_libc_funcs->localtime = + reinterpret_cast<LocaltimeFunction>(dlsym(RTLD_NEXT, "localtime")); + g_libc_funcs->localtime64 = + reinterpret_cast<LocaltimeFunction>(dlsym(RTLD_NEXT, "localtime64")); + g_libc_funcs->localtime_r = + reinterpret_cast<LocaltimeRFunction>(dlsym(RTLD_NEXT, "localtime_r")); + g_libc_funcs->localtime64_r = + reinterpret_cast<LocaltimeRFunction>(dlsym(RTLD_NEXT, "localtime64_r")); + + if (!g_libc_funcs->localtime || !g_libc_funcs->localtime_r) { + // http://code.google.com/p/chromium/issues/detail?id=16800 + // + // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces + // it with a version which doesn't work. In this case we'll get a NULL + // result. There's not a lot we can do at this point, so we just bodge it! + LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " + "reported to be caused by Nvidia's libGL. You should expect" + " time related functions to misbehave. " + "http://code.google.com/p/chromium/issues/detail?id=16800"; + } + + if (!g_libc_funcs->localtime) + g_libc_funcs->localtime = gmtime; + if (!g_libc_funcs->localtime64) + g_libc_funcs->localtime64 = g_libc_funcs->localtime; + if (!g_libc_funcs->localtime_r) + g_libc_funcs->localtime_r = gmtime_r; + if (!g_libc_funcs->localtime64_r) + g_libc_funcs->localtime64_r = g_libc_funcs->localtime_r; +} + +// Define localtime_override() function with asm name "localtime", so that all +// references to localtime() will resolve to this function. Notice that we need +// to set visibility attribute to "default" to export the symbol, as it is set +// to "hidden" by default in chrome per build/common.gypi. +__attribute__((__visibility__("default"))) struct tm* localtime_override( + const time_t* timep) __asm__("localtime"); + +__attribute__((__visibility__("default"))) struct tm* localtime_override( + const time_t* timep) { + if (g_am_zygote_or_renderer && g_use_localtime_override) { + static struct tm time_struct; + static char timezone_string[64]; + ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, + sizeof(timezone_string)); + return &time_struct; + } + + CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + struct tm* res = + base::UnsanitizedCfiCall(g_libc_funcs, &LibcFunctions::localtime)(timep); +#if defined(MEMORY_SANITIZER) + if (res) + __msan_unpoison(res, sizeof(*res)); + if (res->tm_zone) + __msan_unpoison_string(res->tm_zone); +#endif + return res; +} + +// Use same trick to override localtime64(), localtime_r() and localtime64_r(). +__attribute__((__visibility__("default"))) struct tm* localtime64_override( + const time_t* timep) __asm__("localtime64"); + +__attribute__((__visibility__("default"))) struct tm* localtime64_override( + const time_t* timep) { + if (g_am_zygote_or_renderer && g_use_localtime_override) { + static struct tm time_struct; + static char timezone_string[64]; + ProxyLocaltimeCallToBrowser(*timep, &time_struct, timezone_string, + sizeof(timezone_string)); + return &time_struct; + } + + CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + struct tm* res = base::UnsanitizedCfiCall(g_libc_funcs, + &LibcFunctions::localtime64)(timep); +#if defined(MEMORY_SANITIZER) + if (res) + __msan_unpoison(res, sizeof(*res)); + if (res->tm_zone) + __msan_unpoison_string(res->tm_zone); +#endif + return res; +} + +__attribute__((__visibility__("default"))) struct tm* localtime_r_override( + const time_t* timep, + struct tm* result) __asm__("localtime_r"); + +__attribute__((__visibility__("default"))) struct tm* localtime_r_override( + const time_t* timep, + struct tm* result) { + if (g_am_zygote_or_renderer && g_use_localtime_override) { + ProxyLocaltimeCallToBrowser(*timep, result, nullptr, 0); + return result; + } + + CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + struct tm* res = base::UnsanitizedCfiCall( + g_libc_funcs, &LibcFunctions::localtime_r)(timep, result); +#if defined(MEMORY_SANITIZER) + if (res) + __msan_unpoison(res, sizeof(*res)); + if (res->tm_zone) + __msan_unpoison_string(res->tm_zone); +#endif + return res; +} + +__attribute__((__visibility__("default"))) struct tm* localtime64_r_override( + const time_t* timep, + struct tm* result) __asm__("localtime64_r"); + +__attribute__((__visibility__("default"))) struct tm* localtime64_r_override( + const time_t* timep, + struct tm* result) { + if (g_am_zygote_or_renderer && g_use_localtime_override) { + ProxyLocaltimeCallToBrowser(*timep, result, nullptr, 0); + return result; + } + + CHECK_EQ(0, pthread_once(&g_libc_funcs_guard, InitLibcLocaltimeFunctions)); + struct tm* res = base::UnsanitizedCfiCall( + g_libc_funcs, &LibcFunctions::localtime64_r)(timep, result); +#if defined(MEMORY_SANITIZER) + if (res) + __msan_unpoison(res, sizeof(*res)); + if (res->tm_zone) + __msan_unpoison_string(res->tm_zone); +#endif + return res; +} + +void SetUseLocaltimeOverride(bool enable) { + g_use_localtime_override = enable; +} + +void SetAmZygoteOrRenderer(bool enable, int backchannel_fd) { + g_am_zygote_or_renderer = enable; + g_backchannel_fd = backchannel_fd; +} + +bool HandleInterceptedCall(int kind, + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + if (kind != METHOD_LOCALTIME) + return false; + + return HandleLocalTime(fd, iter, fds); +} + +} // namespace sandbox diff --git a/chromium/sandbox/linux/services/libc_interceptor.h b/chromium/sandbox/linux/services/libc_interceptor.h new file mode 100644 index 00000000000..c58c9f34604 --- /dev/null +++ b/chromium/sandbox/linux/services/libc_interceptor.h @@ -0,0 +1,75 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_LINUX_SERVICES_LIBC_INTERCEPTOR_H_ +#define SANDBOX_LINUX_SERVICES_LIBC_INTERCEPTOR_H_ + +#include <vector> + +#include "base/files/scoped_file.h" +#include "base/pickle.h" +#include "build/build_config.h" +#include "sandbox/sandbox_export.h" + +namespace sandbox { + +// Sandbox interception of libc calls. +// +// When we are running in a namespace sandbox certain libc calls will fail +// (localtime being the motivating example - it needs to read /etc/localtime). +// We need to intercept these calls and proxy them to a parent process. +// However, these calls may come from us or from our third_party libraries, so +// in some cases we can't just change the code. +// +// It's for these cases that we have the following setup: +// +// We define global functions for those functions which we wish to override. +// Since we will be first in the dynamic resolution order, the dynamic linker +// will point callers to our versions of these functions. However, we have the +// same binary for both the browser and the renderers, which means that our +// overrides will apply in the browser too. +// +// Our replacement functions must handle both cases, and either proxy the call +// to the parent over the IPC back-channel (see +// https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md) +// or use dlsym with RTLD_NEXT to resolve the symbol, ignoring any symbols in +// the current module. Use SetUseLocaltimeOverride() and SetAmZygoteOrRenderer() +// below to control the mode of operation, which defaults using the dlsym +// approach. +// +// Other avenues: +// +// Our first attempt involved some assembly to patch the GOT of the current +// module. This worked, but was platform specific and doesn't catch the case +// where a library makes a call rather than current module. +// +// We also considered patching the function in place, but this would again by +// platform specific and the above technique seems to work well enough. + +// Methods supported over the back-channel to the parent. +// This isn't the full list, values < 32 are reserved for methods called from +// Skia, and values >= 64 are reserved for sandbox_ipc_linux.cc. +enum InterceptedIPCMethods { + METHOD_LOCALTIME = 32, +}; + +// Currently, only METHOD_LOCALTIME, returns false if |kind| is otherwise. +SANDBOX_EXPORT bool HandleInterceptedCall( + int kind, + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + +// On Linux, localtime is overridden to use a synchronous IPC to the browser +// process to determine the locale. This can be disabled, which causes +// localtime to use UTC instead. https://crbug.com/772503. +SANDBOX_EXPORT void SetUseLocaltimeOverride(bool enable); + +// Turns on/off the libc interception. Called by the zygote and inherited by it +// children. |backchannel_fd| must be the fd to use for proxying calls. +SANDBOX_EXPORT void SetAmZygoteOrRenderer(bool enable, int backchannel_fd); + +} // namespace sandbox + +#endif // SANDBOX_LINUX_SERVICES_LIBC_INTERCEPTOR_H_ diff --git a/chromium/sandbox/linux/services/scoped_process_unittest.cc b/chromium/sandbox/linux/services/scoped_process_unittest.cc index 86f97a8cf43..696e38be598 100644 --- a/chromium/sandbox/linux/services/scoped_process_unittest.cc +++ b/chromium/sandbox/linux/services/scoped_process_unittest.cc @@ -63,7 +63,7 @@ TEST(ScopedProcess, DISABLE_ON_ANDROID(ScopedProcessAbort)) { } TEST(ScopedProcess, ScopedProcessSignaled) { - ScopedProcess process(base::Bind(&base::DoNothing)); + ScopedProcess process{base::DoNothing()}; bool got_signaled = false; ASSERT_EQ(0, kill(process.GetPid(), SIGKILL)); int exit_code = process.WaitForExit(&got_signaled); @@ -91,7 +91,7 @@ TEST(ScopedProcess, DiesForReal) { } TEST(ScopedProcess, SynchronizationBasic) { - ScopedProcess process1(base::Bind(&base::DoNothing)); + ScopedProcess process1{base::DoNothing()}; EXPECT_TRUE(process1.WaitForClosureToRun()); ScopedProcess process2(base::Bind(&DoExit)); diff --git a/chromium/sandbox/linux/services/yama_unittests.cc b/chromium/sandbox/linux/services/yama_unittests.cc index 0e8355d08e6..aaa2cb07569 100644 --- a/chromium/sandbox/linux/services/yama_unittests.cc +++ b/chromium/sandbox/linux/services/yama_unittests.cc @@ -158,7 +158,7 @@ SANDBOX_TEST(Yama, RestrictPtraceIsDefault) { return; CHECK(Yama::DisableYamaRestrictions()); - ScopedProcess process1(base::Bind(&base::DoNothing)); + ScopedProcess process1{base::DoNothing()}; if (Yama::IsEnforcing()) { // Check that process1 is protected by Yama, even though it has diff --git a/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc b/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc index ee4754c0cf1..376dbe7f2ea 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc @@ -20,6 +20,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/logging.h" diff --git a/chromium/sandbox/mac/seatbelt_exec.cc b/chromium/sandbox/mac/seatbelt_exec.cc index df8167cf50d..5dc4c9e5e84 100644 --- a/chromium/sandbox/mac/seatbelt_exec.cc +++ b/chromium/sandbox/mac/seatbelt_exec.cc @@ -57,10 +57,6 @@ bool ReadOrWrite(int fd, ssize_t transacted_bytes = HANDLE_EINTR(Traits::Operate(fd, buffer + offset, bytes_to_transact)); if (transacted_bytes < 0) { - if (errno == EAGAIN) { - sched_yield(); - continue; - } logging::PError("%s failed", Traits::kNameString); return false; } @@ -76,21 +72,13 @@ bool ReadOrWrite(int fd, SeatbeltExecClient::SeatbeltExecClient() { if (pipe(pipe_) != 0) logging::PFatal("SeatbeltExecClient: pipe failed"); - - int pipe_flags = fcntl(pipe_[1], F_GETFL); - if (pipe_flags == -1) - logging::PFatal("SeatbeltExecClient: fctnl(F_GETFL) failed"); - - if (fcntl(pipe_[1], F_SETFL, pipe_flags | O_NONBLOCK) == -1) - logging::PFatal("SeatbeltExecClient: fcntl(F_SETFL) failed"); } SeatbeltExecClient::~SeatbeltExecClient() { + if (pipe_[0] != -1) + IGNORE_EINTR(close(pipe_[0])); if (pipe_[1] != -1) IGNORE_EINTR(close(pipe_[1])); - // If pipe() fails, PCHECK() will be hit in the constructor, so this file - // descriptor should always be closed if the proess is alive at this point. - IGNORE_EINTR(close(pipe_[0])); } bool SeatbeltExecClient::SetBooleanParameter(const std::string& key, @@ -110,26 +98,30 @@ void SeatbeltExecClient::SetProfile(const std::string& policy) { policy_.set_profile(policy); } -int SeatbeltExecClient::SendProfileAndGetFD() { +int SeatbeltExecClient::GetReadFD() { + return pipe_[0]; +} + +bool SeatbeltExecClient::SendProfile() { + IGNORE_EINTR(close(pipe_[0])); + pipe_[0] = -1; + std::string serialized_protobuf; if (!policy_.SerializeToString(&serialized_protobuf)) { logging::Error("SeatbeltExecClient: Serializing the profile failed."); - return -1; + return false; } if (!WriteString(serialized_protobuf)) { logging::Error( "SeatbeltExecClient: Writing the serialized profile failed."); - return -1; + return false; } IGNORE_EINTR(close(pipe_[1])); pipe_[1] = -1; - if (pipe_[0] < 0) - logging::Error("SeatbeltExecClient: The pipe returned an invalid fd."); - - return pipe_[0]; + return true; } bool SeatbeltExecClient::WriteString(const std::string& str) { diff --git a/chromium/sandbox/mac/seatbelt_exec.h b/chromium/sandbox/mac/seatbelt_exec.h index 3366d14e65f..cb12c0c5fb1 100644 --- a/chromium/sandbox/mac/seatbelt_exec.h +++ b/chromium/sandbox/mac/seatbelt_exec.h @@ -36,9 +36,14 @@ class SEATBELT_EXPORT SeatbeltExecClient { // Set the actual sandbox profile, using the scheme-like SBPL. void SetProfile(const std::string& policy); - // Sends the policy to the SeatbeltExecServer and returns the communication - // FD. The FD should be mapped into the sandboxed child process. - int SendProfileAndGetFD(); + // This returns the FD used for reading the sandbox profile in the child + // process. The FD should be mapped into the sandboxed child process. + // This must be called before SendProfile() or the returned FD will be -1. + // Callers should check that the returned FD is valid. + int GetReadFD(); + + // Sends the policy to the SeatbeltExecServer and returns success or failure. + bool SendProfile(); // Returns the underlying protobuf for testing purposes. const mac::SandboxPolicy& GetPolicyForTesting() { return policy_; } diff --git a/chromium/sandbox/win/BUILD.gn b/chromium/sandbox/win/BUILD.gn index 01448d4e1e8..4fabf924cd1 100644 --- a/chromium/sandbox/win/BUILD.gn +++ b/chromium/sandbox/win/BUILD.gn @@ -12,8 +12,9 @@ static_library("sandbox") { sources = [ "src/acl.cc", "src/acl.h", - "src/app_container_profile.cc", "src/app_container_profile.h", + "src/app_container_profile_base.cc", + "src/app_container_profile_base.h", "src/broker_services.cc", "src/broker_services.h", "src/crosscall_client.h", diff --git a/chromium/sandbox/win/sandbox_poc/resource.h b/chromium/sandbox/win/sandbox_poc/resource.h index 87ff920ca48..4a2eba6f672 100644 --- a/chromium/sandbox/win/sandbox_poc/resource.h +++ b/chromium/sandbox/win/sandbox_poc/resource.h @@ -1,3 +1,10 @@ +// Copyright (c) 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_ +#define SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_ + //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by sandbox.rc @@ -28,3 +35,5 @@ #define _APS_NEXT_SYMED_VALUE 110 #endif #endif + +#endif // SANDBOX_WIN_SANDBOX_POC_RESOURCE_H_ diff --git a/chromium/sandbox/win/src/app_container_profile.h b/chromium/sandbox/win/src/app_container_profile.h index 33f79381db8..c95c68e5526 100644 --- a/chromium/sandbox/win/src/app_container_profile.h +++ b/chromium/sandbox/win/src/app_container_profile.h @@ -9,13 +9,8 @@ #include <accctrl.h> -#include <memory> -#include <vector> - #include "base/files/file_path.h" -#include "base/memory/ref_counted.h" #include "base/win/scoped_handle.h" -#include "sandbox/win/src/security_capabilities.h" #include "sandbox/win/src/sid.h" namespace sandbox { @@ -24,25 +19,24 @@ class AppContainerProfile { public: // Increments the reference count of this object. The reference count must // be incremented if this interface is given to another component. - void AddRef(); + virtual void AddRef() = 0; // Decrements the reference count of this object. When the reference count // is zero the object is automatically destroyed. // Indicates that the caller is done with this interface. After calling // release no other method should be called. - void Release(); + virtual void Release() = 0; // Get a handle to a registry key for this package. - bool GetRegistryLocation(REGSAM desired_access, base::win::ScopedHandle* key); + virtual bool GetRegistryLocation(REGSAM desired_access, + base::win::ScopedHandle* key) = 0; // Get a folder path to a location for this package. - bool GetFolderPath(base::FilePath* file_path); + virtual bool GetFolderPath(base::FilePath* file_path) = 0; // Get a pipe name usable by this AC. - bool GetPipePath(const wchar_t* pipe_name, base::FilePath* pipe_path); - - // Get the package SID for this AC. - Sid GetPackageSid() const; + virtual bool GetPipePath(const wchar_t* pipe_name, + base::FilePath* pipe_path) = 0; // Do an access check based on this profile for a named object. If method // returns true then access_status reflects whether access was granted and @@ -50,70 +44,29 @@ class AppContainerProfile { // SE_FILE_OBJECT, SE_REGISTRY_KEY, SE_REGISTRY_WOW64_32KEY. See // ::GetNamedSecurityInfo for more information about how the enumeration is // used and what format object_name needs to be. - bool AccessCheck(const wchar_t* object_name, - SE_OBJECT_TYPE object_type, - DWORD desired_access, - DWORD* granted_access, - BOOL* access_status); + virtual bool AccessCheck(const wchar_t* object_name, + SE_OBJECT_TYPE object_type, + DWORD desired_access, + DWORD* granted_access, + BOOL* access_status) = 0; // Adds a capability by name to this profile. - bool AddCapability(const wchar_t* capability_name); + virtual bool AddCapability(const wchar_t* capability_name) = 0; // Adds a capability from a known list. - bool AddCapability(WellKnownCapabilities capability); + virtual bool AddCapability(WellKnownCapabilities capability) = 0; // Adds a capability from a SID - bool AddCapability(const Sid& capability_sid); + virtual bool AddCapabilitySddl(const wchar_t* sddl_sid) = 0; // Adds an impersonation capability by name to this profile. - bool AddImpersonationCapability(const wchar_t* capability_name); + virtual bool AddImpersonationCapability(const wchar_t* capability_name) = 0; // Adds an impersonation capability from a known list. - bool AddImpersonationCapability(WellKnownCapabilities capability); + virtual bool AddImpersonationCapability(WellKnownCapabilities capability) = 0; // Adds an impersonation capability from a SID - bool AddImpersonationCapability(const Sid& capability_sid); + virtual bool AddImpersonationCapabilitySddl(const wchar_t* sddl_sid) = 0; // Enable Low Privilege AC. - void SetEnableLowPrivilegeAppContainer(bool enable); - bool GetEnableLowPrivilegeAppContainer(); - - // Get an allocated SecurityCapabilities object for this App Container. - std::unique_ptr<SecurityCapabilities> GetSecurityCapabilities(); - - // Get a vector of capabilities. - const std::vector<Sid>& GetCapabilities(); - - // Get a vector of impersonation only capabilities. Used if the process needs - // a more privileged token to start. - const std::vector<Sid>& GetImpersonationCapabilities(); - - // Creates a new AppContainerProfile object. This will create a new profile - // if it doesn't already exist. The profile must be deleted manually using - // the Delete method if it's no longer required. - static scoped_refptr<AppContainerProfile> Create(const wchar_t* package_name, - const wchar_t* display_name, - const wchar_t* description); - - // Opens an AppContainerProfile object. No checks will be made on - // whether the package exists or not. - static scoped_refptr<AppContainerProfile> Open(const wchar_t* package_name); - - // Delete a profile based on name. Returns true if successful, or if the - // package doesn't already exist. - static bool Delete(const wchar_t* package_name); - - private: - AppContainerProfile(const Sid& package_sid); - ~AppContainerProfile(); - - bool BuildLowBoxToken(base::win::ScopedHandle* token); - bool AddCapability(const Sid& capability_sid, bool impersonation_only); - - // Standard object-lifetime reference counter. - volatile LONG ref_count_; - Sid package_sid_; - bool enable_low_privilege_app_container_; - std::vector<Sid> capabilities_; - std::vector<Sid> impersonation_capabilities_; - - DISALLOW_COPY_AND_ASSIGN(AppContainerProfile); + virtual void SetEnableLowPrivilegeAppContainer(bool enable) = 0; + virtual bool GetEnableLowPrivilegeAppContainer() = 0; }; } // namespace sandbox diff --git a/chromium/sandbox/win/src/app_container_profile.cc b/chromium/sandbox/win/src/app_container_profile_base.cc index b0cb041e72d..2203b714e75 100644 --- a/chromium/sandbox/win/src/app_container_profile.cc +++ b/chromium/sandbox/win/src/app_container_profile_base.cc @@ -10,7 +10,7 @@ #include "base/strings/stringprintf.h" #include "base/win/scoped_co_mem.h" #include "base/win/scoped_handle.h" -#include "sandbox/win/src/app_container_profile.h" +#include "sandbox/win/src/app_container_profile_base.h" #include "sandbox/win/src/restricted_token_utils.h" #include "sandbox/win/src/win_utils.h" @@ -79,7 +79,7 @@ class ScopedImpersonation { } // namespace // static -scoped_refptr<AppContainerProfile> AppContainerProfile::Create( +AppContainerProfileBase* AppContainerProfileBase::Create( const wchar_t* package_name, const wchar_t* display_name, const wchar_t* description) { @@ -98,11 +98,11 @@ scoped_refptr<AppContainerProfile> AppContainerProfile::Create( if (FAILED(hr)) return nullptr; std::unique_ptr<void, FreeSidDeleter> sid_deleter(package_sid); - return new AppContainerProfile(Sid(package_sid)); + return new AppContainerProfileBase(Sid(package_sid)); } // static -scoped_refptr<AppContainerProfile> AppContainerProfile::Open( +AppContainerProfileBase* AppContainerProfileBase::Open( const wchar_t* package_name) { static auto derive_app_container_sid = reinterpret_cast<DeriveAppContainerSidFromAppContainerNameFunc*>( @@ -117,11 +117,11 @@ scoped_refptr<AppContainerProfile> AppContainerProfile::Open( return nullptr; std::unique_ptr<void, FreeSidDeleter> sid_deleter(package_sid); - return new AppContainerProfile(Sid(package_sid)); + return new AppContainerProfileBase(Sid(package_sid)); } // static -bool AppContainerProfile::Delete(const wchar_t* package_name) { +bool AppContainerProfileBase::Delete(const wchar_t* package_name) { static auto delete_app_container_profile = reinterpret_cast<DeleteAppContainerProfileFunc*>(GetProcAddress( GetModuleHandle(L"userenv"), "DeleteAppContainerProfile")); @@ -131,26 +131,27 @@ bool AppContainerProfile::Delete(const wchar_t* package_name) { return SUCCEEDED(delete_app_container_profile(package_name)); } -AppContainerProfile::AppContainerProfile(const Sid& package_sid) +AppContainerProfileBase::AppContainerProfileBase(const Sid& package_sid) : ref_count_(0), package_sid_(package_sid), enable_low_privilege_app_container_(false) {} -AppContainerProfile::~AppContainerProfile() {} +AppContainerProfileBase::~AppContainerProfileBase() {} -void AppContainerProfile::AddRef() { +void AppContainerProfileBase::AddRef() { ::InterlockedIncrement(&ref_count_); } -void AppContainerProfile::Release() { +void AppContainerProfileBase::Release() { LONG ref_count = ::InterlockedDecrement(&ref_count_); if (ref_count == 0) { delete this; } } -bool AppContainerProfile::GetRegistryLocation(REGSAM desired_access, - base::win::ScopedHandle* key) { +bool AppContainerProfileBase::GetRegistryLocation( + REGSAM desired_access, + base::win::ScopedHandle* key) { static GetAppContainerRegistryLocationFunc* get_app_container_registry_location = reinterpret_cast<GetAppContainerRegistryLocationFunc*>(GetProcAddress( @@ -170,7 +171,7 @@ bool AppContainerProfile::GetRegistryLocation(REGSAM desired_access, return true; } -bool AppContainerProfile::GetFolderPath(base::FilePath* file_path) { +bool AppContainerProfileBase::GetFolderPath(base::FilePath* file_path) { static GetAppContainerFolderPathFunc* get_app_container_folder_path = reinterpret_cast<GetAppContainerFolderPathFunc*>(GetProcAddress( GetModuleHandle(L"userenv"), "GetAppContainerFolderPath")); @@ -186,8 +187,8 @@ bool AppContainerProfile::GetFolderPath(base::FilePath* file_path) { return true; } -bool AppContainerProfile::GetPipePath(const wchar_t* pipe_name, - base::FilePath* pipe_path) { +bool AppContainerProfileBase::GetPipePath(const wchar_t* pipe_name, + base::FilePath* pipe_path) { base::string16 sddl_str; if (!package_sid_.ToSddlString(&sddl_str)) return false; @@ -196,14 +197,15 @@ bool AppContainerProfile::GetPipePath(const wchar_t* pipe_name, return true; } -bool AppContainerProfile::AccessCheck(const wchar_t* object_name, - SE_OBJECT_TYPE object_type, - DWORD desired_access, - DWORD* granted_access, - BOOL* access_status) { +bool AppContainerProfileBase::AccessCheck(const wchar_t* object_name, + SE_OBJECT_TYPE object_type, + DWORD desired_access, + DWORD* granted_access, + BOOL* access_status) { GENERIC_MAPPING generic_mapping; if (!GetGenericMappingForType(object_type, &generic_mapping)) return false; + MapGenericMask(&desired_access, &generic_mapping); PSECURITY_DESCRIPTOR sd = nullptr; PACL dacl = nullptr; if (GetNamedSecurityInfo( @@ -252,20 +254,20 @@ bool AppContainerProfile::AccessCheck(const wchar_t* object_name, access_status); } -bool AppContainerProfile::AddCapability(const wchar_t* capability_name) { +bool AppContainerProfileBase::AddCapability(const wchar_t* capability_name) { return AddCapability(Sid::FromNamedCapability(capability_name), false); } -bool AppContainerProfile::AddCapability(WellKnownCapabilities capability) { +bool AppContainerProfileBase::AddCapability(WellKnownCapabilities capability) { return AddCapability(Sid::FromKnownCapability(capability), false); } -bool AppContainerProfile::AddCapability(const Sid& capability_sid) { - return AddCapability(capability_sid, false); +bool AppContainerProfileBase::AddCapabilitySddl(const wchar_t* sddl_sid) { + return AddCapability(Sid::FromSddlString(sddl_sid), false); } -bool AppContainerProfile::AddCapability(const Sid& capability_sid, - bool impersonation_only) { +bool AppContainerProfileBase::AddCapability(const Sid& capability_sid, + bool impersonation_only) { if (!capability_sid.IsValid()) return false; if (!impersonation_only) @@ -274,48 +276,49 @@ bool AppContainerProfile::AddCapability(const Sid& capability_sid, return true; } -bool AppContainerProfile::AddImpersonationCapability( +bool AppContainerProfileBase::AddImpersonationCapability( const wchar_t* capability_name) { return AddCapability(Sid::FromNamedCapability(capability_name), true); } -bool AppContainerProfile::AddImpersonationCapability( +bool AppContainerProfileBase::AddImpersonationCapability( WellKnownCapabilities capability) { return AddCapability(Sid::FromKnownCapability(capability), true); } -bool AppContainerProfile::AddImpersonationCapability( - const Sid& capability_sid) { - return AddCapability(capability_sid, true); +bool AppContainerProfileBase::AddImpersonationCapabilitySddl( + const wchar_t* sddl_sid) { + return AddCapability(Sid::FromSddlString(sddl_sid), true); } -const std::vector<Sid>& AppContainerProfile::GetCapabilities() { +const std::vector<Sid>& AppContainerProfileBase::GetCapabilities() { return capabilities_; } -const std::vector<Sid>& AppContainerProfile::GetImpersonationCapabilities() { +const std::vector<Sid>& +AppContainerProfileBase::GetImpersonationCapabilities() { return impersonation_capabilities_; } -Sid AppContainerProfile::GetPackageSid() const { +Sid AppContainerProfileBase::GetPackageSid() const { return package_sid_; } -void AppContainerProfile::SetEnableLowPrivilegeAppContainer(bool enable) { +void AppContainerProfileBase::SetEnableLowPrivilegeAppContainer(bool enable) { enable_low_privilege_app_container_ = enable; } -bool AppContainerProfile::GetEnableLowPrivilegeAppContainer() { +bool AppContainerProfileBase::GetEnableLowPrivilegeAppContainer() { return enable_low_privilege_app_container_; } std::unique_ptr<SecurityCapabilities> -AppContainerProfile::GetSecurityCapabilities() { +AppContainerProfileBase::GetSecurityCapabilities() { return std::unique_ptr<SecurityCapabilities>( new SecurityCapabilities(package_sid_, capabilities_)); } -bool AppContainerProfile::BuildLowBoxToken(base::win::ScopedHandle* token) { +bool AppContainerProfileBase::BuildLowBoxToken(base::win::ScopedHandle* token) { return CreateLowBoxToken(nullptr, IMPERSONATION, GetSecurityCapabilities().get(), nullptr, 0, token) == ERROR_SUCCESS; diff --git a/chromium/sandbox/win/src/app_container_profile_base.h b/chromium/sandbox/win/src/app_container_profile_base.h new file mode 100644 index 00000000000..35fb4efdf57 --- /dev/null +++ b/chromium/sandbox/win/src/app_container_profile_base.h @@ -0,0 +1,94 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_SRC_APP_CONTAINER_PROFILE_BASE_H_ +#define SANDBOX_SRC_APP_CONTAINER_PROFILE_BASE_H_ + +#include <windows.h> + +#include <accctrl.h> + +#include <memory> +#include <vector> + +#include "base/files/file_path.h" +#include "base/memory/ref_counted.h" +#include "base/win/scoped_handle.h" +#include "sandbox/win/src/app_container_profile.h" +#include "sandbox/win/src/security_capabilities.h" +#include "sandbox/win/src/sid.h" + +namespace sandbox { + +class AppContainerProfileBase final : public AppContainerProfile { + public: + void AddRef() override; + void Release() override; + bool GetRegistryLocation(REGSAM desired_access, + base::win::ScopedHandle* key) override; + bool GetFolderPath(base::FilePath* file_path) override; + bool GetPipePath(const wchar_t* pipe_name, + base::FilePath* pipe_path) override; + bool AccessCheck(const wchar_t* object_name, + SE_OBJECT_TYPE object_type, + DWORD desired_access, + DWORD* granted_access, + BOOL* access_status) override; + bool AddCapability(const wchar_t* capability_name) override; + bool AddCapability(WellKnownCapabilities capability) override; + bool AddCapabilitySddl(const wchar_t* sddl_sid) override; + bool AddImpersonationCapability(const wchar_t* capability_name) override; + bool AddImpersonationCapability(WellKnownCapabilities capability) override; + bool AddImpersonationCapabilitySddl(const wchar_t* sddl_sid) override; + void SetEnableLowPrivilegeAppContainer(bool enable) override; + bool GetEnableLowPrivilegeAppContainer() override; + + // Get the package SID for this AC. + Sid GetPackageSid() const; + + // Get an allocated SecurityCapabilities object for this App Container. + std::unique_ptr<SecurityCapabilities> GetSecurityCapabilities(); + + // Get a vector of capabilities. + const std::vector<Sid>& GetCapabilities(); + + // Get a vector of impersonation only capabilities. Used if the process needs + // a more privileged token to start. + const std::vector<Sid>& GetImpersonationCapabilities(); + + // Creates a new AppContainerProfile object. This will create a new profile + // if it doesn't already exist. The profile must be deleted manually using + // the Delete method if it's no longer required. + static AppContainerProfileBase* Create(const wchar_t* package_name, + const wchar_t* display_name, + const wchar_t* description); + + // Opens an AppContainerProfile object. No checks will be made on + // whether the package exists or not. + static AppContainerProfileBase* Open(const wchar_t* package_name); + + // Delete a profile based on name. Returns true if successful, or if the + // package doesn't already exist. + static bool Delete(const wchar_t* package_name); + + private: + AppContainerProfileBase(const Sid& package_sid); + ~AppContainerProfileBase(); + + bool BuildLowBoxToken(base::win::ScopedHandle* token); + bool AddCapability(const Sid& capability_sid, bool impersonation_only); + + // Standard object-lifetime reference counter. + volatile LONG ref_count_; + Sid package_sid_; + bool enable_low_privilege_app_container_; + std::vector<Sid> capabilities_; + std::vector<Sid> impersonation_capabilities_; + + DISALLOW_COPY_AND_ASSIGN(AppContainerProfileBase); +}; + +} // namespace sandbox + +#endif // SANDBOX_SRC_APP_CONTAINER_PROFILE_BASE_H_ diff --git a/chromium/sandbox/win/src/app_container_test.cc b/chromium/sandbox/win/src/app_container_test.cc index 7167354b144..cb725280362 100644 --- a/chromium/sandbox/win/src/app_container_test.cc +++ b/chromium/sandbox/win/src/app_container_test.cc @@ -15,7 +15,7 @@ #include "base/win/scoped_handle.h" #include "base/win/scoped_process_information.h" #include "base/win/windows_version.h" -#include "sandbox/win/src/app_container_profile.h" +#include "sandbox/win/src/app_container_profile_base.h" #include "sandbox/win/src/sync_policy_test.h" #include "sandbox/win/src/win_utils.h" #include "sandbox/win/tests/common/controller.h" @@ -144,17 +144,19 @@ class AppContainerProfileTest : public ::testing::Test { return; package_name_ = GenerateRandomPackageName(); broker_services_ = GetBroker(); - profile_ = AppContainerProfile::Create(package_name_.c_str(), L"Name", - L"Description"); policy_ = broker_services_->CreatePolicy(); - policy_->SetAppContainerProfile(profile_.get()); + 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*>( + policy_->GetAppContainerProfile().get()); } void TearDown() override { if (scoped_process_info_.IsValid()) ::TerminateProcess(scoped_process_info_.process_handle(), 0); if (profile_) - AppContainerProfile::Delete(package_name_.c_str()); + AppContainerProfileBase::Delete(package_name_.c_str()); } protected: @@ -175,7 +177,7 @@ class AppContainerProfileTest : public ::testing::Test { std::wstring package_name_; BrokerServices* broker_services_; - scoped_refptr<AppContainerProfile> profile_; + scoped_refptr<AppContainerProfileBase> profile_; scoped_refptr<TargetPolicy> policy_; base::win::ScopedProcessInformation scoped_process_info_; }; @@ -210,6 +212,8 @@ 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, + policy_->SetProcessMitigations(MITIGATION_HEAP_TERMINATE)); } TEST_F(AppContainerProfileTest, NoCapabilities) { diff --git a/chromium/sandbox/win/src/app_container_unittest.cc b/chromium/sandbox/win/src/app_container_unittest.cc index b61541f8aac..f3e70c35f41 100644 --- a/chromium/sandbox/win/src/app_container_unittest.cc +++ b/chromium/sandbox/win/src/app_container_unittest.cc @@ -17,7 +17,7 @@ #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "base/win/windows_version.h" -#include "sandbox/win/src/app_container_profile.h" +#include "sandbox/win/src/app_container_profile_base.h" #include "sandbox/win/src/security_capabilities.h" #include "sandbox/win/src/sid.h" #include "sandbox/win/src/win_utils.h" @@ -143,7 +143,7 @@ void AccessCheckFile(AppContainerProfile* profile, DWORD granted_access; BOOL access_status; ASSERT_TRUE(profile->AccessCheck(path.value().c_str(), SE_FILE_OBJECT, - FILE_READ_DATA, &granted_access, + desired_access, &granted_access, &access_status)); ASSERT_EQ(expected_status, access_status); if (access_status) @@ -181,11 +181,12 @@ TEST(AppContainerTest, CreateAndDeleteAppContainerProfile) { std::wstring package_name = GenerateRandomPackageName(); EXPECT_FALSE(ProfileExist(package_name)); - scoped_refptr<AppContainerProfile> profile = AppContainerProfile::Create( - package_name.c_str(), L"Name", L"Description"); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Create(package_name.c_str(), L"Name", + L"Description"); ASSERT_NE(nullptr, profile.get()); EXPECT_TRUE(ProfileExist(package_name)); - EXPECT_TRUE(AppContainerProfile::Delete(package_name.c_str())); + EXPECT_TRUE(AppContainerProfileBase::Delete(package_name.c_str())); EXPECT_FALSE(ProfileExist(package_name)); } @@ -195,19 +196,20 @@ TEST(AppContainerTest, CreateAndOpenAppContainerProfile) { std::wstring package_name = GenerateRandomPackageName(); EXPECT_FALSE(ProfileExist(package_name)); - scoped_refptr<AppContainerProfile> profile = AppContainerProfile::Create( - package_name.c_str(), L"Name", L"Description"); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Create(package_name.c_str(), L"Name", + L"Description"); ASSERT_NE(nullptr, profile.get()); EXPECT_TRUE(ProfileExist(package_name)); - scoped_refptr<AppContainerProfile> open_profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> open_profile = + AppContainerProfileBase::Open(package_name.c_str()); ASSERT_NE(nullptr, profile.get()); EXPECT_TRUE(::EqualSid(profile->GetPackageSid().GetPSID(), open_profile->GetPackageSid().GetPSID())); - EXPECT_TRUE(AppContainerProfile::Delete(package_name.c_str())); + EXPECT_TRUE(AppContainerProfileBase::Delete(package_name.c_str())); EXPECT_FALSE(ProfileExist(package_name)); - scoped_refptr<AppContainerProfile> open_profile2 = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> open_profile2 = + AppContainerProfileBase::Open(package_name.c_str()); EXPECT_FALSE(ProfileExist(package_name)); } @@ -216,8 +218,8 @@ TEST(AppContainerTest, SetLowPrivilegeAppContainer) { if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1) return; std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Open(package_name.c_str()); ASSERT_NE(nullptr, profile.get()); profile->SetEnableLowPrivilegeAppContainer(true); EXPECT_TRUE(profile->GetEnableLowPrivilegeAppContainer()); @@ -228,8 +230,8 @@ TEST(AppContainerTest, OpenAppContainerProfileAndGetSecurityCapabilities) { return; std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Open(package_name.c_str()); ASSERT_NE(nullptr, profile.get()); std::vector<Sid> capabilities; @@ -245,9 +247,9 @@ TEST(AppContainerTest, OpenAppContainerProfileAndGetSecurityCapabilities) { ASSERT_TRUE(profile->AddCapability(kInternetClient)); capabilities.push_back(Sid::FromKnownCapability(kInternetClient)); - Sid sid_sddl = Sid::FromSddlString(L"S-1-15-3-1"); - ASSERT_TRUE(profile->AddCapability(sid_sddl)); - capabilities.push_back(sid_sddl); + const wchar_t kSddlSid[] = L"S-1-15-3-1"; + ASSERT_TRUE(profile->AddCapabilitySddl(kSddlSid)); + capabilities.push_back(Sid::FromSddlString(kSddlSid)); auto with_capabilities = profile->GetSecurityCapabilities(); ASSERT_TRUE(ValidSecurityCapabilities( with_capabilities.get(), profile->GetPackageSid(), capabilities)); @@ -258,8 +260,9 @@ TEST(AppContainerTest, GetResources) { return; std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = AppContainerProfile::Create( - package_name.c_str(), L"Name", L"Description"); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Create(package_name.c_str(), L"Name", + L"Description"); ASSERT_NE(nullptr, profile.get()); base::win::ScopedHandle key; EXPECT_TRUE(profile->GetRegistryLocation(KEY_READ, &key)); @@ -275,7 +278,7 @@ TEST(AppContainerTest, GetResources) { pipe_path.value().c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, nullptr)); EXPECT_TRUE(pipe_handle.IsValid()); - EXPECT_TRUE(AppContainerProfile::Delete(package_name.c_str())); + EXPECT_TRUE(AppContainerProfileBase::Delete(package_name.c_str())); } TEST(AppContainerTest, AccessCheckFile) { @@ -284,8 +287,8 @@ TEST(AppContainerTest, AccessCheckFile) { // We don't need a valid profile to do the access check tests. std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Open(package_name.c_str()); profile->AddCapability(kInternetClient); base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); @@ -300,6 +303,10 @@ TEST(AppContainerTest, AccessCheckFile) { Sid::FromKnownCapability(kInternetClient), FILE_READ_DATA, FILE_READ_DATA, TRUE); + // Check mapping generic access rights. + AccessCheckFile(profile.get(), path, ::WinBuiltinAnyPackageSid, + GENERIC_READ | GENERIC_EXECUTE, + FILE_GENERIC_READ | FILE_GENERIC_EXECUTE, TRUE); // No support for LPAC less than Win10 RS1. if (base::win::GetVersion() < base::win::VERSION_WIN10_RS1) return; @@ -316,8 +323,8 @@ TEST(AppContainerTest, AccessCheckRegistry) { // We don't need a valid profile to do the access check tests. std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Open(package_name.c_str()); // Ensure the key doesn't exist. RegDeleteKey(HKEY_CURRENT_USER, package_name.c_str()); SECURITY_ATTRIBUTES_SDDL sa( @@ -346,8 +353,8 @@ TEST(AppContainerTest, ImpersonationCapabilities) { return; std::wstring package_name = GenerateRandomPackageName(); - scoped_refptr<AppContainerProfile> profile = - AppContainerProfile::Open(package_name.c_str()); + scoped_refptr<AppContainerProfileBase> profile = + AppContainerProfileBase::Open(package_name.c_str()); ASSERT_NE(nullptr, profile.get()); std::vector<Sid> capabilities; @@ -371,9 +378,9 @@ TEST(AppContainerTest, ImpersonationCapabilities) { impersonation_capabilities.push_back( Sid::FromNamedCapability(L"FakeCapability")); } - Sid sid_sddl = Sid::FromSddlString(L"S-1-15-3-1"); - ASSERT_TRUE(profile->AddImpersonationCapability(sid_sddl)); - impersonation_capabilities.push_back(sid_sddl); + const wchar_t kSddlSid[] = L"S-1-15-3-1"; + ASSERT_TRUE(profile->AddImpersonationCapabilitySddl(kSddlSid)); + impersonation_capabilities.push_back(Sid::FromSddlString(kSddlSid)); ASSERT_TRUE(CompareSidVectors(profile->GetCapabilities(), capabilities)); ASSERT_TRUE(CompareSidVectors(profile->GetImpersonationCapabilities(), impersonation_capabilities)); diff --git a/chromium/sandbox/win/src/broker_services.cc b/chromium/sandbox/win/src/broker_services.cc index ab899956a88..c9415c2b388 100644 --- a/chromium/sandbox/win/src/broker_services.cc +++ b/chromium/sandbox/win/src/broker_services.cc @@ -368,8 +368,8 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, if (inherited_handle_list.size()) ++attribute_count; - scoped_refptr<AppContainerProfile> profile = - policy_base->GetAppContainerProfile(); + scoped_refptr<AppContainerProfileBase> profile = + policy_base->GetAppContainerProfileBase(); if (profile) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return SBOX_ERROR_BAD_PARAMS; @@ -441,7 +441,7 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // Construct the thread pool here in case it is expensive. // The thread pool is shared by all the targets if (!thread_pool_) - thread_pool_ = base::MakeUnique<Win2kThreadPool>(); + thread_pool_ = std::make_unique<Win2kThreadPool>(); // Create the TargetProcess object and spawn the target suspended. Note that // Brokerservices does not own the target object. It is owned by the Policy. @@ -481,7 +481,7 @@ ResultCode BrokerServicesBase::SpawnTarget(const wchar_t* exe_path, // the job object generates notifications using the completion port. if (job.IsValid()) { std::unique_ptr<JobTracker> tracker = - base::MakeUnique<JobTracker>(std::move(job), policy_base); + std::make_unique<JobTracker>(std::move(job), policy_base); // There is no obvious recovery after failure here. Previous version with // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 diff --git a/chromium/sandbox/win/src/file_policy_test.cc b/chromium/sandbox/win/src/file_policy_test.cc index 59d6532aa36..3eb1bb64513 100644 --- a/chromium/sandbox/win/src/file_policy_test.cc +++ b/chromium/sandbox/win/src/file_policy_test.cc @@ -291,7 +291,8 @@ TEST(FilePolicyTest, AllowNtCreateWithNativePath) { ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str()); EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff)); - std::transform(nt_path.begin(), nt_path.end(), nt_path.begin(), std::tolower); + for (wchar_t& c : nt_path) + c = std::tolower(c); ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str()); EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff)); } diff --git a/chromium/sandbox/win/src/filesystem_interception.h b/chromium/sandbox/win/src/filesystem_interception.h index d5d83318b1c..d9d92f7fa4f 100644 --- a/chromium/sandbox/win/src/filesystem_interception.h +++ b/chromium/sandbox/win/src/filesystem_interception.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_FILESYSTEM_INTERCEPTION_H_ +#define SANDBOX_WIN_SRC_FILESYSTEM_INTERCEPTION_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__ -#define SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__ - namespace sandbox { extern "C" { @@ -64,4 +64,4 @@ TargetNtSetInformationFile(NtSetInformationFileFunction orig_SetInformationFile, } // namespace sandbox -#endif // SANDBOX_SRC_FILESYSTEM_INTERCEPTION_H__ +#endif // SANDBOX_WIN_SRC_FILESYSTEM_INTERCEPTION_H_ diff --git a/chromium/sandbox/win/src/handle_closer.cc b/chromium/sandbox/win/src/handle_closer.cc index 72e64bc0379..3e2f1f00932 100644 --- a/chromium/sandbox/win/src/handle_closer.cc +++ b/chromium/sandbox/win/src/handle_closer.cc @@ -147,7 +147,7 @@ bool HandleCloser::SetupHandleList(void* buffer, size_t buffer_bytes) { output = &list_entry->handle_type[0]; // Copy the typename and set the offset and count. - i->first._Copy_s(output, i->first.size(), i->first.size()); + i->first.copy(output, i->first.size()); *(output += i->first.size()) = L'\0'; output++; list_entry->offset_to_names = diff --git a/chromium/sandbox/win/src/heap_helper.h b/chromium/sandbox/win/src/heap_helper.h index 63ce34570cd..302a3c4e29d 100644 --- a/chromium/sandbox/win/src/heap_helper.h +++ b/chromium/sandbox/win/src/heap_helper.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_HEAP_HELPER_H_ +#define SANDBOX_WIN_SRC_HEAP_HELPER_H_ + #include <windows.h> #include "base/win/windows_version.h" @@ -19,3 +22,5 @@ bool HeapFlags(HANDLE handle, DWORD* flags); HANDLE FindCsrPortHeap(); } // namespace sandbox + +#endif // SANDBOX_WIN_SRC_HEAP_HELPER_H_ diff --git a/chromium/sandbox/win/src/interception.cc b/chromium/sandbox/win/src/interception.cc index 600f7b19cc4..47a8a65dc7d 100644 --- a/chromium/sandbox/win/src/interception.cc +++ b/chromium/sandbox/win/src/interception.cc @@ -276,7 +276,7 @@ bool InterceptionManager::SetupDllInfo(const InterceptionData& data, dll_info->record_bytes = required; dll_info->offset_to_functions = required; dll_info->num_functions = 0; - data.dll._Copy_s(dll_info->dll_name, data.dll.size(), data.dll.size()); + data.dll.copy(dll_info->dll_name, data.dll.size()); dll_info->dll_name[data.dll.size()] = L'\0'; return true; @@ -317,12 +317,12 @@ bool InterceptionManager::SetupInterceptionInfo(const InterceptionData& data, function->interceptor_address = data.interceptor_address; char* names = function->function; - data.function._Copy_s(names, name_bytes, name_bytes); + data.function.copy(names, name_bytes); names += name_bytes; *names++ = '\0'; // interceptor follows the function_name - data.interceptor._Copy_s(names, interceptor_bytes, interceptor_bytes); + data.interceptor.copy(names, interceptor_bytes); names += interceptor_bytes; *names++ = '\0'; diff --git a/chromium/sandbox/win/src/interceptors_64.h b/chromium/sandbox/win/src/interceptors_64.h index d1b2e5776d4..1016b7cfd64 100644 --- a/chromium/sandbox/win/src/interceptors_64.h +++ b/chromium/sandbox/win/src/interceptors_64.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_INTERCEPTORS_64_H_ +#define SANDBOX_WIN_SRC_INTERCEPTORS_64_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_INTERCEPTORS_64_H_ -#define SANDBOX_SRC_INTERCEPTORS_64_H_ - namespace sandbox { extern "C" { @@ -314,4 +314,4 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetConfigureOPMProtectedOutput64( } // namespace sandbox -#endif // SANDBOX_SRC_INTERCEPTORS_64_H_ +#endif // SANDBOX_WIN_SRC_INTERCEPTORS_64_H_ diff --git a/chromium/sandbox/win/src/job.cc b/chromium/sandbox/win/src/job.cc index 831825cd486..cb1c6b9f475 100644 --- a/chromium/sandbox/win/src/job.cc +++ b/chromium/sandbox/win/src/job.cc @@ -37,22 +37,26 @@ DWORD Job::Init(JobLevel security_level, case JOB_LOCKDOWN: { jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; + FALLTHROUGH; } case JOB_RESTRICTED: { jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_WRITECLIPBOARD; jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_READCLIPBOARD; jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES; jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_GLOBALATOMS; + FALLTHROUGH; } case JOB_LIMITED_USER: { jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DISPLAYSETTINGS; jeli.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_ACTIVE_PROCESS; jeli.BasicLimitInformation.ActiveProcessLimit = 1; + FALLTHROUGH; } case JOB_INTERACTIVE: { jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS; jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_DESKTOP; jbur.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS; + FALLTHROUGH; } case JOB_UNPROTECTED: { if (memory_limit) { diff --git a/chromium/sandbox/win/src/named_pipe_interception.h b/chromium/sandbox/win/src/named_pipe_interception.h index 276b4cf0b90..8eedd14b31a 100644 --- a/chromium/sandbox/win/src/named_pipe_interception.h +++ b/chromium/sandbox/win/src/named_pipe_interception.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_NAMED_PIPE_INTERCEPTION_H_ +#define SANDBOX_WIN_SRC_NAMED_PIPE_INTERCEPTION_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__ -#define SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__ - namespace sandbox { extern "C" { @@ -38,4 +38,4 @@ TargetCreateNamedPipeW(CreateNamedPipeWFunction orig_CreateNamedPipeW, } // namespace sandbox -#endif // SANDBOX_SRC_NAMED_PIPE_INTERCEPTION_H__ +#endif // SANDBOX_WIN_SRC_NAMED_PIPE_INTERCEPTION_H_ diff --git a/chromium/sandbox/win/src/policy_low_level.cc b/chromium/sandbox/win/src/policy_low_level.cc index 86e2a13dcad..d2c9a6f8564 100644 --- a/chromium/sandbox/win/src/policy_low_level.cc +++ b/chromium/sandbox/win/src/policy_low_level.cc @@ -265,6 +265,7 @@ bool PolicyRule::AddStringMatch(RuleType rule_type, if (L'?' == current_char[1]) { ++current_char; } + FALLTHROUGH; default: fragment += *current_char; last_char = kLastCharIsAlpha; diff --git a/chromium/sandbox/win/src/policy_target.h b/chromium/sandbox/win/src/policy_target.h index 8a2b437095e..373714e197c 100644 --- a/chromium/sandbox/win/src/policy_target.h +++ b/chromium/sandbox/win/src/policy_target.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_POLICY_TARGET_H_ +#define SANDBOX_WIN_SRC_POLICY_TARGET_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_POLICY_TARGET_H__ -#define SANDBOX_SRC_POLICY_TARGET_H__ - namespace sandbox { struct CountedParameterSetBase; @@ -42,4 +42,4 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenThreadTokenEx( } // namespace sandbox -#endif // SANDBOX_SRC_POLICY_TARGET_H__ +#endif // SANDBOX_WIN_SRC_POLICY_TARGET_H_ diff --git a/chromium/sandbox/win/src/process_mitigations.cc b/chromium/sandbox/win/src/process_mitigations.cc index c6c2d38144b..54c756aece4 100644 --- a/chromium/sandbox/win/src/process_mitigations.cc +++ b/chromium/sandbox/win/src/process_mitigations.cc @@ -431,20 +431,22 @@ bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process, return true; } +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 | + 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_IMAGE_LOAD_PREFER_SYS32; +} + bool CanSetProcessMitigationsPostStartup(MitigationFlags flags) { // All of these mitigations can be enabled after startup. - return !( - flags & - ~(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_IMAGE_LOAD_PREFER_SYS32)); + return !(flags & ~GetAllowedPostStartupProcessMitigations()); } bool CanSetProcessMitigationsPreStartup(MitigationFlags flags) { diff --git a/chromium/sandbox/win/src/process_mitigations.h b/chromium/sandbox/win/src/process_mitigations.h index 5d9b667ec84..cf1844a471a 100644 --- a/chromium/sandbox/win/src/process_mitigations.h +++ b/chromium/sandbox/win/src/process_mitigations.h @@ -38,6 +38,9 @@ void ConvertProcessMitigationsToPolicy(MitigationFlags flags, bool ApplyProcessMitigationsToSuspendedProcess(HANDLE process, MitigationFlags flags); +// Returns the list of process mitigations which can be enabled post startup. +MitigationFlags GetAllowedPostStartupProcessMitigations(); + // Returns true if all the supplied flags can be set after a process starts. bool CanSetProcessMitigationsPostStartup(MitigationFlags flags); diff --git a/chromium/sandbox/win/src/process_thread_interception.h b/chromium/sandbox/win/src/process_thread_interception.h index c4b483cb801..2608d7d31ea 100644 --- a/chromium/sandbox/win/src/process_thread_interception.h +++ b/chromium/sandbox/win/src/process_thread_interception.h @@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_PROCESS_THREAD_INTERCEPTION_H_ +#define SANDBOX_WIN_SRC_PROCESS_THREAD_INTERCEPTION_H_ + #include <windows.h> #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__ -#define SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__ - namespace sandbox { namespace { @@ -98,4 +98,4 @@ TargetCreateThread(CreateThreadFunction orig_CreateThread, } // namespace sandbox -#endif // SANDBOX_SRC_PROCESS_THREAD_INTERCEPTION_H__ +#endif // SANDBOX_WIN_SRC_PROCESS_THREAD_INTERCEPTION_H_ diff --git a/chromium/sandbox/win/src/registry_interception.h b/chromium/sandbox/win/src/registry_interception.h index c3cbde02e72..f47e56ce39c 100644 --- a/chromium/sandbox/win/src/registry_interception.h +++ b/chromium/sandbox/win/src/registry_interception.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_REGISTRY_INTERCEPTION_H_ +#define SANDBOX_WIN_SRC_REGISTRY_INTERCEPTION_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_REGISTRY_INTERCEPTION_H__ -#define SANDBOX_SRC_REGISTRY_INTERCEPTION_H__ - namespace sandbox { extern "C" { @@ -35,4 +35,4 @@ SANDBOX_INTERCEPT NTSTATUS WINAPI TargetNtOpenKeyEx( } // namespace sandbox -#endif // SANDBOX_SRC_REGISTRY_INTERCEPTION_H__ +#endif // SANDBOX_WIN_SRC_REGISTRY_INTERCEPTION_H_ diff --git a/chromium/sandbox/win/src/resolver.h b/chromium/sandbox/win/src/resolver.h index 3091d2f94e6..3ce427b74b9 100644 --- a/chromium/sandbox/win/src/resolver.h +++ b/chromium/sandbox/win/src/resolver.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_RESOLVER_H_ +#define SANDBOX_WIN_SRC_RESOLVER_H_ + // Defines ResolverThunk, the interface for classes that perform interceptions. // For more details see // http://dev.chromium.org/developers/design-documents/sandbox . @@ -11,9 +14,6 @@ #include "base/macros.h" #include "sandbox/win/src/nt_internals.h" -#ifndef SANDBOX_SRC_RESOLVER_H__ -#define SANDBOX_SRC_RESOLVER_H__ - namespace sandbox { // A resolver is the object in charge of performing the actual interception of @@ -104,4 +104,4 @@ class ResolverThunk { } // namespace sandbox -#endif // SANDBOX_SRC_RESOLVER_H__ +#endif // SANDBOX_WIN_SRC_RESOLVER_H_ diff --git a/chromium/sandbox/win/src/restricted_token_unittest.cc b/chromium/sandbox/win/src/restricted_token_unittest.cc index fad38cc8c20..6c674d54993 100644 --- a/chromium/sandbox/win/src/restricted_token_unittest.cc +++ b/chromium/sandbox/win/src/restricted_token_unittest.cc @@ -128,6 +128,39 @@ void CheckLowBoxToken(const base::win::ScopedHandle& token, EXPECT_TRUE(::EqualSid(capabilities->Groups[index].Sid, security_capabilities->Capabilities[index].Sid)); } + + DWORD length_needed = 0; + ::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, nullptr, 0, + &length_needed); + ASSERT_EQ(::GetLastError(), DWORD{ERROR_INSUFFICIENT_BUFFER}); + + std::vector<char> security_desc_buffer(length_needed); + SECURITY_DESCRIPTOR* security_desc = + reinterpret_cast<SECURITY_DESCRIPTOR*>(security_desc_buffer.data()); + + ASSERT_TRUE(::GetKernelObjectSecurity(token.Get(), DACL_SECURITY_INFORMATION, + security_desc, length_needed, + &length_needed)); + + ATL::CSecurityDesc token_sd(*security_desc); + ATL::CSid check_sid( + static_cast<SID*>(security_capabilities->AppContainerSid)); + bool package_sid_found = false; + + ATL::CDacl dacl; + ASSERT_TRUE(token_sd.GetDacl(&dacl)); + unsigned int ace_count = dacl.GetAceCount(); + for (unsigned int i = 0; i < ace_count; ++i) { + ATL::CSid sid; + ACCESS_MASK mask = 0; + BYTE type = 0; + dacl.GetAclEntry(i, &sid, &mask, &type); + if (sid == check_sid && mask == TOKEN_ALL_ACCESS && + type == ACCESS_ALLOWED_ACE_TYPE) { + package_sid_found = true; + } + } + ASSERT_TRUE(package_sid_found); } // Checks if a sid is in the restricting list of the restricted token. diff --git a/chromium/sandbox/win/src/restricted_token_utils.cc b/chromium/sandbox/win/src/restricted_token_utils.cc index 104ae07caab..2653090910c 100644 --- a/chromium/sandbox/win/src/restricted_token_utils.cc +++ b/chromium/sandbox/win/src/restricted_token_utils.cc @@ -23,6 +23,34 @@ namespace sandbox { +namespace { + +DWORD GetObjectSecurityDescriptor(HANDLE handle, + SECURITY_INFORMATION security_info, + std::vector<char>* security_desc_buffer, + PSECURITY_DESCRIPTOR* security_desc) { + DWORD last_error = 0; + DWORD length_needed = 0; + + ::GetKernelObjectSecurity(handle, security_info, nullptr, 0, &length_needed); + last_error = ::GetLastError(); + if (last_error != ERROR_INSUFFICIENT_BUFFER) + return last_error; + + security_desc_buffer->resize(length_needed); + *security_desc = + reinterpret_cast<PSECURITY_DESCRIPTOR>(security_desc_buffer->data()); + + if (!::GetKernelObjectSecurity(handle, security_info, *security_desc, + length_needed, &length_needed)) { + return ::GetLastError(); + } + + return ERROR_SUCCESS; +} + +} // namespace + DWORD CreateRestrictedToken(TokenLevel security_level, IntegrityLevel integrity_level, TokenType token_type, @@ -243,31 +271,21 @@ DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) { } DWORD HardenTokenIntegrityLevelPolicy(HANDLE token) { - DWORD last_error = 0; - DWORD length_needed = 0; - - ::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, nullptr, 0, - &length_needed); - - last_error = ::GetLastError(); - if (last_error != ERROR_INSUFFICIENT_BUFFER) + std::vector<char> security_desc_buffer; + PSECURITY_DESCRIPTOR security_desc = nullptr; + DWORD last_error = GetObjectSecurityDescriptor( + token, LABEL_SECURITY_INFORMATION, &security_desc_buffer, &security_desc); + if (last_error != ERROR_SUCCESS) 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 = nullptr; BOOL sacl_present = false; BOOL sacl_defaulted = false; if (!::GetSecurityDescriptorSacl(security_desc, &sacl_present, &sacl, - &sacl_defaulted)) + &sacl_defaulted)) { return ::GetLastError(); + } for (DWORD ace_index = 0; ace_index < sacl->AceCount; ++ace_index) { PSYSTEM_MANDATORY_LABEL_ACE ace; @@ -343,7 +361,7 @@ DWORD CreateLowBoxToken(HANDLE base_token, // Default from NtCreateLowBoxToken is a Primary token. if (token_type == PRIMARY) { - token->Set(token_lowbox_handle.Take()); + *token = std::move(token_lowbox_handle); return ERROR_SUCCESS; } @@ -354,7 +372,23 @@ DWORD CreateLowBoxToken(HANDLE base_token, return ::GetLastError(); } - token->Set(dup_handle); + // Copy security descriptor from primary token as the new object will have + // the DACL from the current token's default DACL. + base::win::ScopedHandle token_for_sd(dup_handle); + std::vector<char> security_desc_buffer; + PSECURITY_DESCRIPTOR security_desc = nullptr; + DWORD last_error = GetObjectSecurityDescriptor( + token_lowbox_handle.Get(), DACL_SECURITY_INFORMATION, + &security_desc_buffer, &security_desc); + if (last_error != ERROR_SUCCESS) + return last_error; + + if (!::SetKernelObjectSecurity(token_for_sd.Get(), DACL_SECURITY_INFORMATION, + security_desc)) { + return ::GetLastError(); + } + + *token = std::move(token_for_sd); return ERROR_SUCCESS; } diff --git a/chromium/sandbox/win/src/sandbox_policy.h b/chromium/sandbox/win/src/sandbox_policy.h index 4a110fa9d93..46260c3e302 100644 --- a/chromium/sandbox/win/src/sandbox_policy.h +++ b/chromium/sandbox/win/src/sandbox_policy.h @@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include "base/memory/scoped_refptr.h" #include "base/strings/string16.h" #include "sandbox/win/src/sandbox_types.h" #include "sandbox/win/src/security_level.h" @@ -253,8 +254,15 @@ class TargetPolicy { // Enable OPM API emulation when in Win32k lockdown. virtual bool GetEnableOPMRedirection() = 0; - // Configure policy to use an AppContainer profile. - virtual ResultCode SetAppContainerProfile(AppContainerProfile* profile) = 0; + // Configure policy to use an AppContainer profile. |package_name| is the + // name of the profile to use. Specifying True for |create_profile| ensures + // the profile exists, if set to False process creation will fail if the + // profile has not already been created. + virtual ResultCode AddAppContainerProfile(const wchar_t* package_name, + bool create_profile) = 0; + + // Get the configured AppContainerProfile. + virtual scoped_refptr<AppContainerProfile> GetAppContainerProfile() = 0; protected: ~TargetPolicy() {} diff --git a/chromium/sandbox/win/src/sandbox_policy_base.cc b/chromium/sandbox/win/src/sandbox_policy_base.cc index 471fc75a325..d18fe40284d 100644 --- a/chromium/sandbox/win/src/sandbox_policy_base.cc +++ b/chromium/sandbox/win/src/sandbox_policy_base.cc @@ -267,7 +267,7 @@ void PolicyBase::DestroyAlternateDesktop() { } ResultCode PolicyBase::SetIntegrityLevel(IntegrityLevel integrity_level) { - if (_app_container_profile) + if (app_container_profile_) return SBOX_ERROR_BAD_PARAMS; integrity_level_ = integrity_level; return SBOX_ALL_OK; @@ -288,7 +288,7 @@ ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { return SBOX_ERROR_UNSUPPORTED; DCHECK(sid); - if (lowbox_sid_ || _app_container_profile) + if (lowbox_sid_ || app_container_profile_) return SBOX_ERROR_BAD_PARAMS; if (!ConvertStringSidToSid(sid, &lowbox_sid_)) @@ -298,7 +298,7 @@ ResultCode PolicyBase::SetLowBox(const wchar_t* sid) { } ResultCode PolicyBase::SetProcessMitigations(MitigationFlags flags) { - if (!CanSetProcessMitigationsPreStartup(flags)) + if (app_container_profile_ || !CanSetProcessMitigationsPreStartup(flags)) return SBOX_ERROR_BAD_PARAMS; mitigations_ = flags; return SBOX_ALL_OK; @@ -544,8 +544,10 @@ bool PolicyBase::OnJobEmpty(HANDLE job) { } ResultCode PolicyBase::SetDisconnectCsrss() { -// Does not work on 32-bit. -#if defined(_WIN64) +// Does not work on 32-bit, and the ASAN runtime falls over with the +// CreateThread EAT patch used when this is enabled. +// See https://crbug.com/783296#c27. +#if defined(_WIN64) && !defined(ADDRESS_SANITIZER) if (base::win::GetVersion() >= base::win::VERSION_WIN10) { is_csrss_connected_ = false; return AddKernelObjectToClose(L"ALPC Port", nullptr); @@ -596,21 +598,41 @@ bool PolicyBase::GetEnableOPMRedirection() { return enable_opm_redirection_; } -ResultCode PolicyBase::SetAppContainerProfile(AppContainerProfile* profile) { +ResultCode PolicyBase::AddAppContainerProfile(const wchar_t* package_name, + bool create_profile) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return SBOX_ERROR_UNSUPPORTED; - DCHECK(profile); - if (lowbox_sid_ || _app_container_profile || + DCHECK(package_name); + if (lowbox_sid_ || app_container_profile_ || integrity_level_ != INTEGRITY_LEVEL_LAST) return SBOX_ERROR_BAD_PARAMS; - _app_container_profile = profile; + if (create_profile) { + app_container_profile_ = AppContainerProfileBase::Create( + package_name, L"Chrome Sandbox", L"Profile for Chrome Sandbox"); + } else { + app_container_profile_ = AppContainerProfileBase::Open(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. + delayed_mitigations_ = + mitigations_ & GetAllowedPostStartupProcessMitigations(); + DCHECK(delayed_mitigations_ == (mitigations_ & ~MITIGATION_SEHOP)); + mitigations_ = 0; return SBOX_ALL_OK; } scoped_refptr<AppContainerProfile> PolicyBase::GetAppContainerProfile() { - return _app_container_profile; + return GetAppContainerProfileBase(); +} + +scoped_refptr<AppContainerProfileBase> +PolicyBase::GetAppContainerProfileBase() { + return app_container_profile_; } ResultCode PolicyBase::SetupAllInterceptions(TargetProcess* target) { diff --git a/chromium/sandbox/win/src/sandbox_policy_base.h b/chromium/sandbox/win/src/sandbox_policy_base.h index fddea2b2e19..d532221be7e 100644 --- a/chromium/sandbox/win/src/sandbox_policy_base.h +++ b/chromium/sandbox/win/src/sandbox_policy_base.h @@ -16,10 +16,11 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/process/launch.h" #include "base/strings/string16.h" #include "base/win/scoped_handle.h" -#include "sandbox/win/src/app_container_profile.h" +#include "sandbox/win/src/app_container_profile_base.h" #include "sandbox/win/src/crosscall_server.h" #include "sandbox/win/src/handle_closer.h" #include "sandbox/win/src/ipc_tags.h" @@ -73,7 +74,12 @@ class PolicyBase final : public TargetPolicy { void SetLockdownDefaultDacl() override; void SetEnableOPMRedirection() override; bool GetEnableOPMRedirection() override; - ResultCode SetAppContainerProfile(AppContainerProfile* profile) override; + ResultCode AddAppContainerProfile(const wchar_t* package_name, + bool create_profile) override; + scoped_refptr<AppContainerProfile> GetAppContainerProfile() override; + + // Get the AppContainer profile as its internal type. + scoped_refptr<AppContainerProfileBase> GetAppContainerProfileBase(); // Creates a Job object with the level specified in a previous call to // SetJobLevel(). @@ -102,8 +108,6 @@ class PolicyBase final : public TargetPolicy { HANDLE GetStdoutHandle(); HANDLE GetStderrHandle(); - scoped_refptr<AppContainerProfile> GetAppContainerProfile(); - // Returns the list of handles being shared with the target process. const base::HandlesToInheritVector& GetHandlesBeingShared(); @@ -174,7 +178,7 @@ class PolicyBase final : public TargetPolicy { base::HandlesToInheritVector handles_to_share_; bool enable_opm_redirection_; - scoped_refptr<AppContainerProfile> _app_container_profile; + scoped_refptr<AppContainerProfileBase> app_container_profile_; DISALLOW_COPY_AND_ASSIGN(PolicyBase); }; diff --git a/chromium/sandbox/win/src/sandbox_types.h b/chromium/sandbox/win/src/sandbox_types.h index 48ac305df72..e2638996185 100644 --- a/chromium/sandbox/win/src/sandbox_types.h +++ b/chromium/sandbox/win/src/sandbox_types.h @@ -107,6 +107,12 @@ enum ResultCode : int { SBOX_ERROR_CANNOT_WRITE_INTERCEPTION_THUNK = 42, // Cannot find the base address of the new process. SBOX_ERROR_CANNOT_FIND_BASE_ADDRESS = 43, + // Cannot create the AppContainer profile. + SBOX_ERROR_CREATE_APPCONTAINER_PROFILE = 44, + // Cannot create the AppContainer as the main executable can't be accessed. + SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_ACCESS_CHECK = 45, + // Cannot create the AppContainer as adding a capability failed. + SBOX_ERROR_CREATE_APPCONTAINER_PROFILE_CAPABILITY = 46, // Placeholder for last item of the enum. SBOX_ERROR_LAST }; diff --git a/chromium/sandbox/win/src/sidestep/mini_disassembler.cpp b/chromium/sandbox/win/src/sidestep/mini_disassembler.cpp index 1e8e0bd9729..d7fd83df001 100644 --- a/chromium/sandbox/win/src/sidestep/mini_disassembler.cpp +++ b/chromium/sandbox/win/src/sidestep/mini_disassembler.cpp @@ -109,6 +109,7 @@ InstructionType MiniDisassembler::ProcessPrefixes(unsigned char* start_byte, (*size)++; // we got a prefix, so add one and check next byte ProcessPrefixes(start_byte + 1, size); + break; default: break; // not a prefix byte } diff --git a/chromium/sandbox/win/src/sync_interception.h b/chromium/sandbox/win/src/sync_interception.h index f7894c63ec4..c21e7ee7b21 100644 --- a/chromium/sandbox/win/src/sync_interception.h +++ b/chromium/sandbox/win/src/sync_interception.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_SYNC_INTERCEPTION_H_ +#define SANDBOX_WIN_SRC_SYNC_INTERCEPTION_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_SYNC_INTERCEPTION_H__ -#define SANDBOX_SRC_SYNC_INTERCEPTION_H__ - namespace sandbox { extern "C" { @@ -43,4 +43,4 @@ TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent, } // namespace sandbox -#endif // SANDBOX_SRC_SYNC_INTERCEPTION_H__ +#endif // SANDBOX_WIN_SRC_SYNC_INTERCEPTION_H_ diff --git a/chromium/sandbox/win/src/target_interceptions.h b/chromium/sandbox/win/src/target_interceptions.h index 6350d083681..fac1c65c270 100644 --- a/chromium/sandbox/win/src/target_interceptions.h +++ b/chromium/sandbox/win/src/target_interceptions.h @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef SANDBOX_WIN_SRC_TARGET_INTERCEPTIONS_H_ +#define SANDBOX_WIN_SRC_TARGET_INTERCEPTIONS_H_ + #include "sandbox/win/src/nt_internals.h" #include "sandbox/win/src/sandbox_types.h" -#ifndef SANDBOX_SRC_TARGET_INTERCEPTIONS_H__ -#define SANDBOX_SRC_TARGET_INTERCEPTIONS_H__ - namespace sandbox { extern "C" { @@ -40,4 +40,4 @@ TargetNtUnmapViewOfSection(NtUnmapViewOfSectionFunction orig_UnmapViewOfSection, } // namespace sandbox -#endif // SANDBOX_SRC_TARGET_INTERCEPTIONS_H__ +#endif // SANDBOX_WIN_SRC_TARGET_INTERCEPTIONS_H_ |