broker_process.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sandbox/linux/syscall_broker/broker_process.h"
  5. #include <fcntl.h>
  6. #include <signal.h>
  7. #include <sys/stat.h>
  8. #include <sys/syscall.h>
  9. #include <sys/types.h>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12. #include <algorithm>
  13. #include <memory>
  14. #include <string>
  15. #include <utility>
  16. #include <vector>
  17. #include "base/callback.h"
  18. #include "base/files/file_util.h"
  19. #include "base/logging.h"
  20. #include "base/posix/eintr_wrapper.h"
  21. #include "base/process/process_metrics.h"
  22. #include "build/build_config.h"
  23. #include "sandbox/linux/syscall_broker/broker_channel.h"
  24. #include "sandbox/linux/syscall_broker/broker_client.h"
  25. #include "sandbox/linux/syscall_broker/broker_host.h"
  26. #include "sandbox/linux/syscall_broker/broker_permission_list.h"
  27. namespace sandbox {
  28. namespace syscall_broker {
  29. BrokerProcess::BrokerProcess(absl::optional<BrokerSandboxConfig> policy,
  30. BrokerType broker_type,
  31. bool fast_check_in_client,
  32. bool quiet_failures_for_tests)
  33. : policy_(std::move(policy)),
  34. broker_type_(broker_type),
  35. fast_check_in_client_(fast_check_in_client),
  36. quiet_failures_for_tests_(quiet_failures_for_tests) {}
  37. BrokerProcess::~BrokerProcess() {
  38. if (initialized_) {
  39. if (broker_client_.get()) {
  40. // Closing the socket should be enough to notify the child to die,
  41. // unless it has been duplicated.
  42. CloseChannel();
  43. }
  44. PCHECK(0 == kill(broker_pid_, SIGKILL));
  45. siginfo_t process_info;
  46. // Reap the child.
  47. int ret = HANDLE_EINTR(waitid(P_PID, broker_pid_, &process_info, WEXITED));
  48. PCHECK(0 == ret);
  49. }
  50. }
  51. bool BrokerProcess::ForkSignalBasedBroker(
  52. BrokerSideCallback broker_process_init_callback) {
  53. BrokerChannel::EndPoint ipc_reader, ipc_writer;
  54. BrokerChannel::CreatePair(&ipc_reader, &ipc_writer);
  55. int child_pid = fork();
  56. if (child_pid == -1)
  57. return false;
  58. if (child_pid) {
  59. // We are the parent and we have just forked our broker process.
  60. ipc_reader.reset();
  61. // If we already know our policy we can go ahead and create the
  62. // BrokerClient.
  63. CHECK(policy_);
  64. broker_client_ = std::make_unique<BrokerClient>(
  65. *policy_, std::move(ipc_writer), fast_check_in_client_);
  66. broker_pid_ = child_pid;
  67. initialized_ = true;
  68. return true;
  69. }
  70. // We are the broker process. Make sure to close the writer's end so that
  71. // we get notified if the client disappears.
  72. ipc_writer.reset();
  73. CHECK(std::move(broker_process_init_callback).Run(*policy_));
  74. BrokerHost broker_host_signal_based(*policy_, std::move(ipc_reader));
  75. broker_host_signal_based.LoopAndHandleRequests();
  76. _exit(1);
  77. NOTREACHED();
  78. return false;
  79. }
  80. bool BrokerProcess::Fork(BrokerSideCallback broker_process_init_callback) {
  81. CHECK(!initialized_);
  82. #if !defined(THREAD_SANITIZER)
  83. DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle()));
  84. #endif
  85. return ForkSignalBasedBroker(std::move(broker_process_init_callback));
  86. }
  87. bool BrokerProcess::IsSyscallAllowed(int sysno) const {
  88. return IsSyscallBrokerable(sysno, fast_check_in_client_);
  89. }
  90. bool BrokerProcess::IsSyscallBrokerable(int sysno, bool fast_check) const {
  91. CHECK(policy_);
  92. // The syscalls unavailable on aarch64 are all blocked by Android's default
  93. // seccomp policy, even on non-aarch64 architectures. I.e., the syscalls XX()
  94. // with a corresponding XXat() versions are typically unavailable in aarch64
  95. // and are default disabled in Android. So, we should refuse to broker them
  96. // to be consistent with the platform's restrictions.
  97. switch (sysno) {
  98. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  99. case __NR_access:
  100. #endif
  101. case __NR_faccessat:
  102. case __NR_faccessat2:
  103. return !fast_check || policy_->allowed_command_set.test(COMMAND_ACCESS);
  104. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  105. case __NR_mkdir:
  106. #endif
  107. case __NR_mkdirat:
  108. return !fast_check || policy_->allowed_command_set.test(COMMAND_MKDIR);
  109. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  110. case __NR_open:
  111. #endif
  112. case __NR_openat:
  113. return !fast_check || policy_->allowed_command_set.test(COMMAND_OPEN);
  114. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  115. case __NR_readlink:
  116. #endif
  117. case __NR_readlinkat:
  118. return !fast_check || policy_->allowed_command_set.test(COMMAND_READLINK);
  119. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  120. case __NR_rename:
  121. #endif
  122. #ifdef __NR_renameat
  123. case __NR_renameat:
  124. #endif
  125. case __NR_renameat2:
  126. return !fast_check || policy_->allowed_command_set.test(COMMAND_RENAME);
  127. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  128. case __NR_rmdir:
  129. return !fast_check || policy_->allowed_command_set.test(COMMAND_RMDIR);
  130. #endif
  131. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  132. case __NR_stat:
  133. case __NR_lstat:
  134. #endif
  135. #if defined(__NR_fstatat)
  136. case __NR_fstatat:
  137. #endif
  138. #if defined(__NR_fstatat64)
  139. case __NR_fstatat64:
  140. #endif
  141. #if defined(__x86_64__) || defined(__aarch64__) || defined(__riscv)
  142. case __NR_newfstatat:
  143. #endif
  144. return !fast_check || policy_->allowed_command_set.test(COMMAND_STAT);
  145. #if defined(__i386__) || defined(__arm__) || \
  146. (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
  147. case __NR_stat64:
  148. case __NR_lstat64:
  149. // For security purposes, map stat64 to COMMAND_STAT permission. The
  150. // separate COMMAND_STAT64 only exists to broker different-sized
  151. // argument structs.
  152. return !fast_check || policy_->allowed_command_set.test(COMMAND_STAT);
  153. #endif
  154. #if !defined(__aarch64__) && !BUILDFLAG(IS_ANDROID) && !defined(__riscv)
  155. case __NR_unlink:
  156. return !fast_check || policy_->allowed_command_set.test(COMMAND_UNLINK);
  157. #endif
  158. case __NR_unlinkat:
  159. // If rmdir() doesn't exist, unlinkat is used with AT_REMOVEDIR.
  160. return !fast_check || policy_->allowed_command_set.test(COMMAND_RMDIR) ||
  161. policy_->allowed_command_set.test(COMMAND_UNLINK);
  162. default:
  163. return false;
  164. }
  165. }
  166. void BrokerProcess::CloseChannel() {
  167. broker_client_.reset();
  168. }
  169. } // namespace syscall_broker
  170. } // namespace sandbox