diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-24 11:30:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-30 12:56:19 +0000 |
commit | 6036726eb981b6c4b42047513b9d3f4ac865daac (patch) | |
tree | 673593e70678e7789766d1f732eb51f613a2703b /chromium/sandbox | |
parent | 466052c4e7c052268fd931888cd58961da94c586 (diff) | |
download | qtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz |
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/sandbox')
25 files changed, 400 insertions, 71 deletions
diff --git a/chromium/sandbox/BUILD.gn b/chromium/sandbox/BUILD.gn index dd29a82cd93..a67c55140b4 100644 --- a/chromium/sandbox/BUILD.gn +++ b/chromium/sandbox/BUILD.gn @@ -30,6 +30,7 @@ group("sandbox") { public_deps = [ "//sandbox/mac:seatbelt", "//sandbox/mac:seatbelt_extension", + "//sandbox/mac:system_services", "//sandbox/mac/mojom", ] } else if (is_linux || is_android) { diff --git a/chromium/sandbox/linux/BUILD.gn b/chromium/sandbox/linux/BUILD.gn index 6f43c6cb60b..754fe5a50b3 100644 --- a/chromium/sandbox/linux/BUILD.gn +++ b/chromium/sandbox/linux/BUILD.gn @@ -319,25 +319,6 @@ if (is_linux) { # TODO fix this and re-enable this warning. "-Wno-sign-compare", ] - - import("//build/config/compiler/compiler.gni") - import("//build/config/sanitizers/sanitizers.gni") - if (is_component_build || using_sanitizer) { - # WARNING! We remove this config so that we don't accidentally - # pick up the //build/config:rpath_for_built_shared_libraries - # sub-config. However, this means that we need to duplicate any - # other flags that executable_config might have. - configs -= [ "//build/config:executable_config" ] - if (!use_gold) { - ldflags = [ "-Wl,--disable-new-dtags" ] - } - } - - # We also do not want to pick up any of the other sanitizer - # flags (i.e. we do not want to build w/ the sanitizers at all). - # This is safe to delete unconditionally, because it is part of the - # default configs and empty when not using the sanitizers. - configs -= [ "//build/config/sanitizers:default_sanitizer_flags" ] } } diff --git a/chromium/sandbox/linux/PRESUBMIT.py b/chromium/sandbox/linux/PRESUBMIT.py index 0ece8e6aa25..d23105a01a1 100644 --- a/chromium/sandbox/linux/PRESUBMIT.py +++ b/chromium/sandbox/linux/PRESUBMIT.py @@ -27,7 +27,7 @@ def PostUploadHook(cl, change, output_api): return output_api.EnsureCQIncludeTrybotsAreAdded( cl, [ - 'master.tryserver.chromium.android:android_arm64_dbg_recipe', + 'luci.chromium.try:android_arm64_dbg_recipe', 'master.tryserver.chromium.android:android_compile_x64_dbg', 'master.tryserver.chromium.android:android_compile_x86_dbg', ], diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc index 46a54ed1233..426ea0757e5 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc @@ -174,9 +174,11 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno, } if (sysno == __NR_madvise) { - // Only allow MADV_DONTNEED and MADV_FREE. + // Only allow MADV_DONTNEED, MADV_RANDOM, MADV_NORMAL and MADV_FREE. const Arg<int> advice(2); - return If(AnyOf(advice == MADV_DONTNEED + return If(AnyOf(advice == MADV_DONTNEED, + advice == MADV_RANDOM, + advice == MADV_NORMAL #if defined(MADV_FREE) // MADV_FREE was introduced in Linux 4.5 and started being // defined in glibc 2.24. diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc index ca812d8a1ed..f3ffb33ad64 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc @@ -361,7 +361,7 @@ BPF_DEATH_TEST_C(BaselinePolicy, DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), BaselinePolicy) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, &ts); } #if !defined(GRND_RANDOM) diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc index b572a618ff7..793be730250 100644 --- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc +++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions_unittests.cc @@ -98,7 +98,7 @@ BPF_DEATH_TEST_C(ParameterRestrictions, DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), RestrictClockIdPolicy) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, &ts); } #if !defined(OS_ANDROID) diff --git a/chromium/sandbox/linux/services/credentials_unittest.cc b/chromium/sandbox/linux/services/credentials_unittest.cc index 41c04bbcc29..ab6039479a3 100644 --- a/chromium/sandbox/linux/services/credentials_unittest.cc +++ b/chromium/sandbox/linux/services/credentials_unittest.cc @@ -40,7 +40,9 @@ struct CapFreeDeleter { }; // Wrapper to manage libcap2's cap_t type. -typedef std::unique_ptr<typeof(*((cap_t)0)), CapFreeDeleter> ScopedCap; +typedef std::unique_ptr<std::remove_reference<decltype(*((cap_t)0))>::type, + CapFreeDeleter> + ScopedCap; bool WorkingDirectoryIsRoot() { char current_dir[PATH_MAX]; diff --git a/chromium/sandbox/linux/suid/process_util_linux.c b/chromium/sandbox/linux/suid/process_util_linux.c index d28d5766c34..0008331839d 100644 --- a/chromium/sandbox/linux/suid/process_util_linux.c +++ b/chromium/sandbox/linux/suid/process_util_linux.c @@ -8,7 +8,9 @@ // Needed for O_DIRECTORY, must be defined before fcntl.h is included // (and it can be included earlier than the explicit #include below // in some versions of glibc). +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include "sandbox/linux/suid/process_util.h" diff --git a/chromium/sandbox/linux/suid/sandbox.c b/chromium/sandbox/linux/suid/sandbox.c index 66f68ef1387..854819bfbb4 100644 --- a/chromium/sandbox/linux/suid/sandbox.c +++ b/chromium/sandbox/linux/suid/sandbox.c @@ -6,7 +6,9 @@ #include "sandbox/linux/suid/common/sandbox.h" +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include <asm/unistd.h> #include <errno.h> #include <fcntl.h> diff --git a/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc b/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc index 18e4c14a657..e1babb8f5ac 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_file_permission.cc @@ -204,8 +204,8 @@ bool BrokerFilePermission::CheckStat(const char* requested_filename, if (CheckAccessInternal(requested_filename, F_OK, file_to_access)) return true; - // Allow stat() on leading directories if have create permission. - if (!allow_create_) + // Allow stat() on leading directories if have create or stat() permission. + if (!(allow_create_ || allow_stat_with_intermediates_)) return false; // NOTE: ValidatePath proved requested_length != 0; @@ -214,7 +214,10 @@ bool BrokerFilePermission::CheckStat(const char* requested_filename, // Special case for root: only one slash, otherwise must have a second // slash in the right spot to avoid substring matches. + // |allow_stat_with_intermediates_| can match on the full path, and + // |allow_create_| only matches a leading directory. if ((requested_length == 1 && requested_filename[0] == '/') || + (allow_stat_with_intermediates_ && path_ == requested_filename) || (requested_length < path_.length() && memcmp(path_.c_str(), requested_filename, requested_length) == 0 && path_.c_str()[requested_length] == '/')) { @@ -231,18 +234,23 @@ const char* BrokerFilePermission::GetErrorMessageForTests() { return "Invalid BrokerFilePermission"; } -BrokerFilePermission::BrokerFilePermission(const std::string& path, - bool recursive, - bool temporary_only, - bool allow_read, - bool allow_write, - bool allow_create) +BrokerFilePermission::BrokerFilePermission( + const std::string& path, + RecursionOption recurse_opt, + PersistenceOption persist_opt, + ReadPermission read_perm, + WritePermission write_perm, + CreatePermission create_perm, + StatWithIntermediatesPermission stat_perm) : path_(path), - recursive_(recursive), - temporary_only_(temporary_only), - allow_read_(allow_read), - allow_write_(allow_write), - allow_create_(allow_create) { + recursive_(recurse_opt == RecursionOption::kRecursive), + temporary_only_(persist_opt == PersistenceOption::kTemporaryOnly), + allow_read_(read_perm == ReadPermission::kAllowRead), + allow_write_(write_perm == WritePermission::kAllowWrite), + allow_create_(create_perm == CreatePermission::kAllowCreate), + allow_stat_with_intermediates_( + stat_perm == + StatWithIntermediatesPermission::kAllowStatWithIntermediates) { // Must have enough length for a '/' CHECK(path_.length() > 0) << GetErrorMessageForTests(); @@ -251,7 +259,7 @@ BrokerFilePermission::BrokerFilePermission(const std::string& path, // Don't allow temporary creation without create permission if (temporary_only_) - CHECK(allow_create) << GetErrorMessageForTests(); + CHECK(allow_create_) << GetErrorMessageForTests(); // Recursive paths must have a trailing slash, absolutes must not. const char last_char = *(path_.rbegin()); diff --git a/chromium/sandbox/linux/syscall_broker/broker_file_permission.h b/chromium/sandbox/linux/syscall_broker/broker_file_permission.h index 4261eb357ac..654bd268058 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_file_permission.h +++ b/chromium/sandbox/linux/syscall_broker/broker_file_permission.h @@ -13,6 +13,16 @@ namespace sandbox { namespace syscall_broker { +enum class RecursionOption { kNonRecursive = 0, kRecursive }; +enum class PersistenceOption { kPermanent = 0, kTemporaryOnly }; +enum class ReadPermission { kBlockRead = 0, kAllowRead }; +enum class WritePermission { kBlockWrite = 0, kAllowWrite }; +enum class CreatePermission { kBlockCreate = 0, kAllowCreate }; +enum class StatWithIntermediatesPermission { + kBlockStatWithIntermediates = 0, + kAllowStatWithIntermediates +}; + // BrokerFilePermission defines a path for whitelisting. // Pick the correct static factory method to create a permission. // CheckOpen and CheckAccess are async signal safe. @@ -25,40 +35,81 @@ class SANDBOX_EXPORT BrokerFilePermission { BrokerFilePermission& operator=(const BrokerFilePermission&) = default; static BrokerFilePermission ReadOnly(const std::string& path) { - return BrokerFilePermission(path, false, false, true, false, false); + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kPermanent, + ReadPermission::kAllowRead, WritePermission::kBlockWrite, + CreatePermission::kBlockCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission ReadOnlyRecursive(const std::string& path) { - return BrokerFilePermission(path, true, false, true, false, false); + return BrokerFilePermission( + path, RecursionOption::kRecursive, PersistenceOption::kPermanent, + ReadPermission::kAllowRead, WritePermission::kBlockWrite, + CreatePermission::kBlockCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission WriteOnly(const std::string& path) { - return BrokerFilePermission(path, false, false, false, true, false); + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kPermanent, + ReadPermission::kBlockRead, WritePermission::kAllowWrite, + CreatePermission::kBlockCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission ReadWrite(const std::string& path) { - return BrokerFilePermission(path, false, false, true, true, false); + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kPermanent, + ReadPermission::kAllowRead, WritePermission::kAllowWrite, + CreatePermission::kBlockCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission ReadWriteCreate(const std::string& path) { - return BrokerFilePermission(path, false, false, true, true, true); + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kPermanent, + ReadPermission::kAllowRead, WritePermission::kAllowWrite, + CreatePermission::kAllowCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission ReadWriteCreateRecursive( const std::string& path) { - return BrokerFilePermission(path, true, false, true, true, true); + return BrokerFilePermission( + path, RecursionOption::kRecursive, PersistenceOption::kPermanent, + ReadPermission::kAllowRead, WritePermission::kAllowWrite, + CreatePermission::kAllowCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } // Temporary files must always be newly created and do not confer rights to // use pre-existing files of the same name. static BrokerFilePermission ReadWriteCreateTemporary( const std::string& path) { - return BrokerFilePermission(path, false, true, true, true, true); + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kTemporaryOnly, + ReadPermission::kAllowRead, WritePermission::kAllowWrite, + CreatePermission::kAllowCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); } static BrokerFilePermission ReadWriteCreateTemporaryRecursive( const std::string& path) { - return BrokerFilePermission(path, true, true, true, true, true); + return BrokerFilePermission( + path, RecursionOption::kRecursive, PersistenceOption::kTemporaryOnly, + ReadPermission::kAllowRead, WritePermission::kAllowWrite, + CreatePermission::kAllowCreate, + StatWithIntermediatesPermission::kBlockStatWithIntermediates); + } + + static BrokerFilePermission StatOnlyWithIntermediateDirs( + const std::string& path) { + return BrokerFilePermission( + path, RecursionOption::kNonRecursive, PersistenceOption::kPermanent, + ReadPermission::kBlockRead, WritePermission::kBlockWrite, + CreatePermission::kBlockCreate, + StatWithIntermediatesPermission::kAllowStatWithIntermediates); } // Returns true if |requested_filename| is allowed to be accessed @@ -104,11 +155,12 @@ class SANDBOX_EXPORT BrokerFilePermission { // NOTE: Validates the permission and dies if invalid! BrokerFilePermission(const std::string& path, - bool recursive, - bool temporary_only, - bool allow_read, - bool allow_write, - bool allow_create); + RecursionOption recurse_opt, + PersistenceOption persist_opt, + ReadPermission read_perm, + WritePermission write_perm, + CreatePermission create_perm, + StatWithIntermediatesPermission stat_perm); // ValidatePath checks |path| and returns true if these conditions are met // * Greater than 0 length @@ -138,6 +190,8 @@ class SANDBOX_EXPORT BrokerFilePermission { bool allow_read_; bool allow_write_; bool allow_create_; + // Allow stat() for |path| and all intermediate dirs. + bool allow_stat_with_intermediates_; }; } // namespace syscall_broker diff --git a/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc b/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc index 006cc494d56..7cd41b6f03e 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_file_permission_unittest.cc @@ -260,6 +260,30 @@ TEST(BrokerFilePermission, ReadWriteCreateTemporaryRecursive) { // expected. } +TEST(BrokerFilePermission, StatOnlyWithIntermediateDirs) { + const char kPath[] = "/tmp/good/path"; + const char kLeading1[] = "/"; + const char kLeading2[] = "/tmp"; + const char kLeading3[] = "/tmp/good/path"; + const char kTrailing[] = "/tmp/good/path/bad"; + + BrokerFilePermission perm = + BrokerFilePermission::StatOnlyWithIntermediateDirs(kPath); + // No open or access permission. + ASSERT_FALSE(perm.CheckOpen(kPath, O_RDONLY, NULL, NULL)); + ASSERT_FALSE(perm.CheckOpen(kPath, O_WRONLY, NULL, NULL)); + ASSERT_FALSE(perm.CheckOpen(kPath, O_RDWR, NULL, NULL)); + ASSERT_FALSE(perm.CheckAccess(kPath, R_OK, NULL)); + ASSERT_FALSE(perm.CheckAccess(kPath, W_OK, NULL)); + + // Stat for all leading paths, but not trailing paths. + ASSERT_TRUE(perm.CheckStat(kPath, NULL)); + ASSERT_TRUE(perm.CheckStat(kLeading1, NULL)); + ASSERT_TRUE(perm.CheckStat(kLeading2, NULL)); + ASSERT_TRUE(perm.CheckStat(kLeading3, NULL)); + ASSERT_FALSE(perm.CheckStat(kTrailing, NULL)); +} + TEST(BrokerFilePermission, ValidatePath) { EXPECT_TRUE(BrokerFilePermissionTester::ValidatePath("/path")); EXPECT_TRUE(BrokerFilePermissionTester::ValidatePath("/")); diff --git a/chromium/sandbox/linux/syscall_broker/broker_process.cc b/chromium/sandbox/linux/syscall_broker/broker_process.cc index c510b8afd5f..82ab4a76c28 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_process.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_process.cc @@ -103,6 +103,80 @@ bool BrokerProcess::Init( return false; } +bool BrokerProcess::IsSyscallAllowed(int sysno) const { + switch (sysno) { +#if !defined(__aarch64__) + case __NR_access: +#endif + case __NR_faccessat: + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_ACCESS); + +#if !defined(__aarch64__) + case __NR_mkdir: +#endif + case __NR_mkdirat: + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_MKDIR); + +#if !defined(__aarch64__) + case __NR_open: +#endif + case __NR_openat: + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_OPEN); + +#if !defined(__aarch64__) + case __NR_readlink: +#endif + case __NR_readlinkat: + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_READLINK); + +#if !defined(__aarch64__) + case __NR_rename: +#endif + case __NR_renameat: + case __NR_renameat2: + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_RENAME); + +#if !defined(__aarch64__) + case __NR_rmdir: + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_RMDIR); +#endif + +#if !defined(__aarch64__) + case __NR_stat: + case __NR_lstat: +#endif +#if defined(__NR_fstatat) + case __NR_fstatat: +#endif +#if defined(__x86_64__) || defined(__aarch64__) + case __NR_newfstatat: +#endif + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_STAT); + +#if defined(__i386__) || defined(__arm__) || defined(__mips32__) + case __NR_stat64: + case __NR_lstat64: + // For security purposes, map stat64 to COMMAND_STAT permission. The + // separate COMMAND_STAT64 only exists to broker different-sized + // argument structs. + return !fast_check_in_client_ || allowed_command_set_.test(COMMAND_STAT); +#endif + +#if !defined(__aarch64__) + case __NR_unlink: +#endif + case __NR_unlinkat: + return !fast_check_in_client_ || + allowed_command_set_.test(COMMAND_UNLINK); + + default: + return false; + } +} + void BrokerProcess::CloseChannel() { broker_client_.reset(); } diff --git a/chromium/sandbox/linux/syscall_broker/broker_process.h b/chromium/sandbox/linux/syscall_broker/broker_process.h index 13599306a18..e994a01d5c1 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_process.h +++ b/chromium/sandbox/linux/syscall_broker/broker_process.h @@ -74,6 +74,14 @@ class SANDBOX_EXPORT BrokerProcess { // Return the PID of the child created by Init(). int broker_pid() const { return broker_pid_; } + // Can be used in bpf_dsl::Policy::EvaluateSyscall() implementations to + // determine if the system call |sysno| should be trapped and forwarded + // to the broker process for handling. This examines the + // |allowed_command_set_| iff |fast_check_in_client_| is true. If + // the fast checks are disabled, then all possible brokerable system + // calls are forwarded to the broker process for handling. + bool IsSyscallAllowed(int sysno) const; + // The following methods are used in place of the equivalently-named // syscalls by the trap handler. They, in turn, forward the call onto // |broker_client_| for further processing. They will all be async signal diff --git a/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc b/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc index 8df69d0a436..553b02a1d42 100644 --- a/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc +++ b/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc @@ -27,6 +27,8 @@ #include "base/macros.h" #include "base/posix/eintr_wrapper.h" #include "base/posix/unix_domain_socket.h" +#include "base/stl_util.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "sandbox/linux/syscall_broker/broker_client.h" #include "sandbox/linux/tests/scoped_temporary_file.h" @@ -1452,5 +1454,85 @@ TEST(BrokerProcess, UnlinkHost) { TestUnlinkHelper(false); } +TEST(BrokerProcess, IsSyscallAllowed) { + const struct { + int sysno; + BrokerCommand command; + } kSyscallToCommandMap[] = { +#if defined(__NR_access) + {__NR_access, COMMAND_ACCESS}, +#endif + {__NR_faccessat, COMMAND_ACCESS}, +#if defined(__NR_mkdir) + {__NR_mkdir, COMMAND_MKDIR}, +#endif + {__NR_mkdirat, COMMAND_MKDIR}, +#if defined(__NR_open) + {__NR_open, COMMAND_OPEN}, +#endif + {__NR_openat, COMMAND_OPEN}, +#if defined(__NR_readlink) + {__NR_readlink, COMMAND_READLINK}, +#endif + {__NR_readlinkat, COMMAND_READLINK}, +#if defined(__NR_rename) + {__NR_rename, COMMAND_RENAME}, +#endif + {__NR_renameat, COMMAND_RENAME}, +#if defined(__NR_rmdir) + {__NR_rmdir, COMMAND_RMDIR}, +#endif +#if defined(__NR_stat) + {__NR_stat, COMMAND_STAT}, +#endif +#if defined(__NR_lstat) + {__NR_lstat, COMMAND_STAT}, +#endif +#if defined(__NR_fstatat) + {__NR_fstatat, COMMAND_STAT}, +#endif +#if defined(__NR_newfstatat) + {__NR_newfstatat, COMMAND_STAT}, +#endif +#if defined(__NR_stat64) + {__NR_stat64, COMMAND_STAT}, +#endif +#if defined(__NR_lstat64) + {__NR_lstat64, COMMAND_STAT}, +#endif +#if defined(__NR_unlink) + {__NR_unlink, COMMAND_UNLINK}, +#endif + {__NR_unlinkat, COMMAND_UNLINK}, + }; + + for (const auto& test : kSyscallToCommandMap) { + // Test with fast_check_in_client. + { + SCOPED_TRACE(base::StringPrintf("fast check, sysno=%d", test.sysno)); + BrokerProcess process(ENOSYS, MakeBrokerCommandSet({test.command}), {}, + true, true); + EXPECT_TRUE(process.IsSyscallAllowed(test.sysno)); + for (const auto& other : kSyscallToCommandMap) { + SCOPED_TRACE(base::StringPrintf("others test, sysno=%d", other.sysno)); + EXPECT_EQ(other.command == test.command, + process.IsSyscallAllowed(other.sysno)); + } + } + + // Test without fast_check_in_client. + { + SCOPED_TRACE(base::StringPrintf("no fast check, sysno=%d", test.sysno)); + BrokerProcess process(ENOSYS, MakeBrokerCommandSet({test.command}), {}, + false, true); + EXPECT_TRUE(process.IsSyscallAllowed(test.sysno)); + for (const auto& other : kSyscallToCommandMap) { + SCOPED_TRACE(base::StringPrintf("others test, sysno=%d", other.sysno)); + EXPECT_TRUE(process.IsSyscallAllowed(other.sysno)); + } + } + } +} + } // namespace syscall_broker } // namespace sandbox diff --git a/chromium/sandbox/mac/BUILD.gn b/chromium/sandbox/mac/BUILD.gn index fd2afe0d907..d1147821a9b 100644 --- a/chromium/sandbox/mac/BUILD.gn +++ b/chromium/sandbox/mac/BUILD.gn @@ -49,6 +49,22 @@ component("seatbelt_extension") { defines = [ "SEATBELT_IMPLEMENTATION" ] } +component("system_services") { + sources = [ + "seatbelt_export.h", + "system_services.cc", + "system_services.h", + ] + libs = [ + "Carbon.framework", + "CoreFoundation.framework", + ] + public_deps = [ + "//base", + ] + defines = [ "SEATBELT_IMPLEMENTATION" ] +} + test("sandbox_mac_unittests") { sources = [ "mojom/struct_traits_unittest.cc", diff --git a/chromium/sandbox/mac/system_services.cc b/chromium/sandbox/mac/system_services.cc new file mode 100644 index 00000000000..caa30bb378b --- /dev/null +++ b/chromium/sandbox/mac/system_services.cc @@ -0,0 +1,37 @@ +// 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/mac/system_services.h" + +#include <Carbon/Carbon.h> +#include <CoreFoundation/CoreFoundation.h> + +#include "base/mac/mac_logging.h" + +extern "C" { +OSStatus SetApplicationIsDaemon(Boolean isDaemon); +void _LSSetApplicationLaunchServicesServerConnectionStatus( + uint64_t flags, + bool (^connection_allowed)(CFDictionaryRef options)); +} // extern "C" + +namespace sandbox { + +void DisableLaunchServices() { + // Allow the process to continue without a LaunchServices ASN. The + // INIT_Process function in HIServices will abort if it cannot connect to + // launchservicesd to get an ASN. By setting this flag, HIServices skips + // that. + OSStatus status = SetApplicationIsDaemon(true); + OSSTATUS_LOG_IF(ERROR, status != noErr, status) << "SetApplicationIsDaemon"; + + // Close any connections to launchservicesd and use an always-false predicate + // to discourage future attempts to connect. + _LSSetApplicationLaunchServicesServerConnectionStatus( + 0, ^bool(CFDictionaryRef options) { + return false; + }); +} + +} // namespace sandbox diff --git a/chromium/sandbox/mac/system_services.h b/chromium/sandbox/mac/system_services.h new file mode 100644 index 00000000000..7c1974c05b1 --- /dev/null +++ b/chromium/sandbox/mac/system_services.h @@ -0,0 +1,23 @@ +// 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_MAC_SYSTEM_SERVICES_H_ +#define SANDBOX_MAC_SYSTEM_SERVICES_H_ + +#include "sandbox/mac/seatbelt_export.h" + +namespace sandbox { + +// Tells LaunchServices that the process is not a normal GUI application, which +// permits the process to call into various Carbon services without requiring +// an ASN. This marks the process as a "daemon". If the process is currently +// connected to LaunchServices, the connection is closed and the system is +// instructed to not attempt to connect again. This does not alter the sandbox +// policy (i.e., direct lookup requests to launchd will not be affected), but +// it instructs system frameworks to not attempt to connect. +SEATBELT_EXPORT void DisableLaunchServices(); + +} // namespace sandbox + +#endif // SANDBOX_MAC_SYSTEM_SERVICES_H_ diff --git a/chromium/sandbox/win/sandbox_poc/main_ui_window.cc b/chromium/sandbox/win/sandbox_poc/main_ui_window.cc index 8576faeb759..89c1be76697 100644 --- a/chromium/sandbox/win/sandbox_poc/main_ui_window.cc +++ b/chromium/sandbox/win/sandbox_poc/main_ui_window.cc @@ -11,12 +11,12 @@ #include <stddef.h> #include <time.h> #include <windowsx.h> -#include <atlbase.h> -#include <atlsecurity.h> + #include <algorithm> #include <sstream> #include "base/logging.h" +#include "base/win/atl.h" #include "sandbox/win/sandbox_poc/resource.h" #include "sandbox/win/src/acl.h" #include "sandbox/win/src/sandbox.h" diff --git a/chromium/sandbox/win/src/process_mitigations.cc b/chromium/sandbox/win/src/process_mitigations.cc index b9be8a4023b..0f38be1166f 100644 --- a/chromium/sandbox/win/src/process_mitigations.cc +++ b/chromium/sandbox/win/src/process_mitigations.cc @@ -77,7 +77,16 @@ bool ApplyProcessMitigationsToCurrentProcess(MitigationFlags flags) { // Check for SetDefaultDllDirectories since it requires KB2533623. if (set_default_dll_directories) { - if (!set_default_dll_directories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) && +#if defined(COMPONENT_BUILD) + const DWORD directory_flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; +#else + // In a non-component build, all DLLs will be loaded manually, or via + // manifest definition, so these flags can be stronger. This prevents DLL + // planting in the application directory. + const DWORD directory_flags = + LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS; +#endif + if (!set_default_dll_directories(directory_flags) && ERROR_ACCESS_DENIED != ::GetLastError()) { return false; } diff --git a/chromium/sandbox/win/src/process_mitigations_unittest.cc b/chromium/sandbox/win/src/process_mitigations_unittest.cc index e13b22ab1a0..046f4a2ba95 100644 --- a/chromium/sandbox/win/src/process_mitigations_unittest.cc +++ b/chromium/sandbox/win/src/process_mitigations_unittest.cc @@ -7,6 +7,7 @@ #include <windows.h> #include "base/files/file_util.h" +#include "base/numerics/safe_conversions.h" #include "base/path_service.h" #include "base/scoped_native_library.h" #include "base/test/test_timeouts.h" @@ -446,7 +447,7 @@ SBOX_TESTS_COMMAND int CheckWin10FontLoad(int argc, wchar_t** argv) { return SBOX_TEST_NOT_FOUND; font_data.resize(len); - int read = file.Read(0, &font_data[0], len); + int read = file.Read(0, &font_data[0], base::checked_cast<int>(len)); file.Close(); if (read != len) diff --git a/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc b/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc index 4e603009bca..e65878e6df7 100644 --- a/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc +++ b/chromium/sandbox/win/src/process_mitigations_win32k_unittest.cc @@ -110,7 +110,7 @@ CreateOPMProtectedOutputsTest(PUNICODE_STRING device_name, return STATUS_SUCCESS; } -ULONG CalculateCertLength(ULONG monitor) { +ULONG CalculateCertLength(DWORD monitor) { return (monitor * 0x800) + 0xabc; } @@ -356,12 +356,14 @@ bool RunTestsOnVideoOutputConfigure(uintptr_t monitor_index, bool RunTestsOnVideoOutputFinishInitialization(uintptr_t monitor_index, IOPMVideoOutput* video_output) { OPM_ENCRYPTED_INITIALIZATION_PARAMETERS init_params = {}; - memset(init_params.abEncryptedInitializationParameters, 'a' + monitor_index, + memset(init_params.abEncryptedInitializationParameters, + 'a' + static_cast<DWORD>(monitor_index), sizeof(init_params.abEncryptedInitializationParameters)); HRESULT hr = video_output->FinishInitialization(&init_params); if (FAILED(hr)) return false; - memset(init_params.abEncryptedInitializationParameters, 'Z' + monitor_index, + memset(init_params.abEncryptedInitializationParameters, + 'Z' + static_cast<DWORD>(monitor_index), sizeof(init_params.abEncryptedInitializationParameters)); hr = video_output->FinishInitialization(&init_params); if (SUCCEEDED(hr)) @@ -380,7 +382,8 @@ bool RunTestsOnVideoOutputStartInitialization(uintptr_t monitor_index, if (FAILED(hr)) return false; - if (certificate_length != CalculateCertLength(monitor_index)) + if (certificate_length != + CalculateCertLength(static_cast<DWORD>(monitor_index))) return false; for (ULONG i = 0; i < certificate_length; ++i) { diff --git a/chromium/sandbox/win/src/restricted_token_unittest.cc b/chromium/sandbox/win/src/restricted_token_unittest.cc index 6c674d54993..6fa8cbd2bae 100644 --- a/chromium/sandbox/win/src/restricted_token_unittest.cc +++ b/chromium/sandbox/win/src/restricted_token_unittest.cc @@ -6,12 +6,9 @@ #include "sandbox/win/src/restricted_token.h" -#define _ATL_NO_EXCEPTIONS -#include <atlbase.h> -#include <atlsecurity.h> - #include <vector> +#include "base/win/atl.h" #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" #include "sandbox/win/src/security_capabilities.h" diff --git a/chromium/sandbox/win/src/security_level.h b/chromium/sandbox/win/src/security_level.h index b238ad00aa0..1036b34a669 100644 --- a/chromium/sandbox/win/src/security_level.h +++ b/chromium/sandbox/win/src/security_level.h @@ -197,10 +197,15 @@ const MitigationFlags MITIGATION_HIGH_ENTROPY_ASLR = 0x00000080; // PROCESS_CREATION_MITIGATION_POLICY_STRICT_HANDLE_CHECKS_ALWAYS_ON. const MitigationFlags MITIGATION_STRICT_HANDLE_CHECKS = 0x00000100; -// Sets the DLL search order to LOAD_LIBRARY_SEARCH_DEFAULT_DIRS. Additional -// directories can be added via the Windows AddDllDirectory() function. -// http://msdn.microsoft.com/en-us/library/windows/desktop/hh310515 -// Must be enabled after startup. +// Strengthens the DLL search order. See +// http://msdn.microsoft.com/en-us/library/windows/desktop/hh310515. In a +// component build - sets this to LOAD_LIBRARY_SEARCH_DEFAULT_DIRS allowing +// additional directories to be added via Windows AddDllDirectory() function, +// but preserving current load order. In a non-component build, all DLLs should +// be loaded manually, so strenthen to LOAD_LIBRARY_SEARCH_SYSTEM32 | +// LOAD_LIBRARY_SEARCH_USER_DIRS, removing LOAD_LIBRARY_SEARCH_APPLICATION_DIR, +// preventing DLLs being implicitly loaded from the application path. Must be +// enabled after startup. const MitigationFlags MITIGATION_DLL_SEARCH_ORDER = 0x00000200; // Changes the mandatory integrity level policy on the current process' token diff --git a/chromium/sandbox/win/src/sid_unittest.cc b/chromium/sandbox/win/src/sid_unittest.cc index 5b01d592acc..35c1314139b 100644 --- a/chromium/sandbox/win/src/sid_unittest.cc +++ b/chromium/sandbox/win/src/sid_unittest.cc @@ -6,11 +6,9 @@ #include "sandbox/win/src/sid.h" -#define _ATL_NO_EXCEPTIONS -#include <atlbase.h> -#include <atlsecurity.h> #include <sddl.h> +#include "base/win/atl.h" #include "base/win/windows_version.h" #include "testing/gtest/include/gtest/gtest.h" |