// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/policy/linux/sandbox_linux.h"

#include <dirent.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <limits>
#include <memory>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/scoped_file.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/set_process_title.h"
#include "base/strings/string_number_conversions.h"
#include "base/system/sys_info.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_id_name_manager.h"
#include "build/build_config.h"
#include "sandbox/constants.h"
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/services/credentials.h"
#include "sandbox/linux/services/libc_interceptor.h"
#include "sandbox/linux/services/namespace_sandbox.h"
#include "sandbox/linux/services/proc_util.h"
#include "sandbox/linux/services/resource_limits.h"
#include "sandbox/linux/services/syscall_wrappers.h"
#include "sandbox/linux/services/thread_helpers.h"
#include "sandbox/linux/services/yama.h"
#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
#include "sandbox/linux/syscall_broker/broker_client.h"
#include "sandbox/linux/syscall_broker/broker_command.h"
#include "sandbox/linux/syscall_broker/broker_process.h"
#include "sandbox/linux/system_headers/linux_landlock.h"
#include "sandbox/linux/system_headers/linux_stat.h"
#include "sandbox/policy/features.h"
#include "sandbox/policy/linux/bpf_broker_policy_linux.h"
#include "sandbox/policy/linux/sandbox_seccomp_bpf_linux.h"
#include "sandbox/policy/mojom/sandbox.mojom.h"
#include "sandbox/policy/sandbox.h"
#include "sandbox/policy/sandbox_type.h"
#include "sandbox/policy/switches.h"
#include "sandbox/sandbox_buildflags.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"

#if BUILDFLAG(USING_SANITIZER)
#include <sanitizer/common_interface_defs.h>
#endif

namespace sandbox {
namespace policy {

namespace {

void LogSandboxStarted(const std::string& sandbox_name) {
  const std::string process_type =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kProcessType);
  const std::string activated_sandbox =
      "Activated " + sandbox_name +
      " sandbox for process type: " + process_type + ".";
  VLOG(1) << activated_sandbox;
}

bool IsRunningTSAN() {
#if defined(THREAD_SANITIZER)
  return true;
#else
  return false;
#endif
}

// In processes which must bring up GPU drivers before sandbox initialization,
// we can't ensure that other threads won't be running already.
bool ShouldAllowThreadsDuringSandboxInit(const std::string& process_type,
                                         sandbox::mojom::Sandbox sandbox_type) {
  if (process_type == switches::kGpuProcess) {
    return true;
  }

  if (process_type == switches::kUtilityProcess &&
      sandbox_type == sandbox::mojom::Sandbox::kOnDeviceModelExecution) {
    return true;
  }

  return false;
}

// Get a file descriptor to /proc. Either duplicate |proc_fd| or try to open
// it by using the filesystem directly.
// TODO(jln): get rid of this ugly interface.
base::ScopedFD OpenProc(int proc_fd) {
  int ret_proc_fd = -1;
  if (proc_fd >= 0) {
    // If a handle to /proc is available, use it. This allows to bypass file
    // system restrictions.
    ret_proc_fd =
        HANDLE_EINTR(openat(proc_fd, ".", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
  } else {
    // Otherwise, make an attempt to access the file system directly.
    ret_proc_fd = HANDLE_EINTR(
        openat(AT_FDCWD, "/proc/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
  }
  DCHECK_LE(0, ret_proc_fd);
  return base::ScopedFD(ret_proc_fd);
}

bool UpdateProcessTypeAndEnableSandbox(
    SandboxLinux::Options options,
    const syscall_broker::BrokerSandboxConfig& policy) {
  base::CommandLine::StringVector exec =
      base::CommandLine::ForCurrentProcess()->GetArgs();
  base::CommandLine::Reset();
  base::CommandLine::Init(0, nullptr);
  base::CommandLine::ForCurrentProcess()->InitFromArgv(exec);

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::string new_process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);
  if (!new_process_type.empty()) {
    new_process_type.append("-broker");
  } else {
    new_process_type = "broker";
  }

  VLOG(3) << "UpdateProcessTypeAndEnableSandbox: Updating process type to "
          << new_process_type;
  command_line->AppendSwitchASCII(switches::kProcessType, new_process_type);

  // Update the process title. The argv was already cached by the call to
  // SetProcessTitleFromCommandLine in content_main_runner.cc, so we can pass
  // NULL here (we don't have the original argv at this point).
  base::SetProcessTitleFromCommandLine(nullptr);

  return SandboxSeccompBPF::StartSandboxWithExternalPolicy(
      std::make_unique<BrokerProcessPolicy>(policy.allowed_command_set),
      base::ScopedFD());
}

}  // namespace

SandboxLinux::SandboxLinux()
    : proc_fd_(-1),
      seccomp_bpf_started_(false),
      sandbox_status_flags_(kInvalid),
      pre_initialized_(false),
      seccomp_bpf_supported_(false),
      seccomp_bpf_with_tsync_supported_(false),
      yama_is_enforcing_(false),
      initialize_sandbox_ran_(false),
      setuid_sandbox_client_(SetuidSandboxClient::Create()),
      broker_process_(nullptr) {
  if (!setuid_sandbox_client_) {
    LOG(FATAL) << "Failed to instantiate the setuid sandbox client.";
  }
#if BUILDFLAG(USING_SANITIZER)
  sanitizer_args_ = std::make_unique<__sanitizer_sandbox_arguments>();
  *sanitizer_args_ = {0};
#endif
}

SandboxLinux::~SandboxLinux() {
  if (pre_initialized_) {
    CHECK(initialize_sandbox_ran_);
  }
}

SandboxLinux* SandboxLinux::GetInstance() {
  SandboxLinux* instance = base::Singleton<SandboxLinux>::get();
  CHECK(instance);
  return instance;
}

void SandboxLinux::PreinitializeSandbox() {
  CHECK(!pre_initialized_);
  seccomp_bpf_supported_ = false;
#if BUILDFLAG(USING_SANITIZER)
  // Sanitizers need to open some resources before the sandbox is enabled.
  // This should not fork, not launch threads, not open a directory.
  __sanitizer_sandbox_on_notify(sanitizer_args());
  sanitizer_args_.reset();
#endif

  // Open proc_fd_. It would break the security of the setuid sandbox if it was
  // not closed.
  // If SandboxLinux::PreinitializeSandbox() runs, InitializeSandbox() must run
  // as well.
  proc_fd_ = HANDLE_EINTR(open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC));
  CHECK_GE(proc_fd_, 0);
  // We "pre-warm" the code that detects supports for seccomp BPF.
  if (SandboxSeccompBPF::IsSeccompBPFDesired()) {
    if (!SandboxSeccompBPF::SupportsSandbox()) {
      VLOG(1) << "Lacking support for seccomp-bpf sandbox.";
    } else {
      seccomp_bpf_supported_ = true;
    }

    if (SandboxSeccompBPF::SupportsSandboxWithTsync()) {
      seccomp_bpf_with_tsync_supported_ = true;
    }
  }

  // Yama is a "global", system-level status. We assume it will not regress
  // after startup.
  const int yama_status = Yama::GetStatus();
  yama_is_enforcing_ = (yama_status & Yama::STATUS_PRESENT) &&
                       (yama_status & Yama::STATUS_ENFORCING);
  pre_initialized_ = true;
}

void SandboxLinux::EngageNamespaceSandbox(bool from_zygote) {
  CHECK(EngageNamespaceSandboxInternal(from_zygote));
}

bool SandboxLinux::EngageNamespaceSandboxIfPossible() {
  return EngageNamespaceSandboxInternal(false /* from_zygote */);
}

std::vector<int> SandboxLinux::GetFileDescriptorsToClose() {
  std::vector<int> fds;
  if (proc_fd_ >= 0) {
    fds.push_back(proc_fd_);
  }
  return fds;
}

int SandboxLinux::GetStatus() {
  if (!pre_initialized_) {
    return 0;
  }
  if (sandbox_status_flags_ == kInvalid) {
    // Initialize sandbox_status_flags_.
    sandbox_status_flags_ = 0;
    if (setuid_sandbox_client_->IsSandboxed()) {
      sandbox_status_flags_ |= kSUID;
      if (setuid_sandbox_client_->IsInNewPIDNamespace())
        sandbox_status_flags_ |= kPIDNS;
      if (setuid_sandbox_client_->IsInNewNETNamespace())
        sandbox_status_flags_ |= kNetNS;
    } else if (NamespaceSandbox::InNewUserNamespace()) {
      sandbox_status_flags_ |= kUserNS;
      if (NamespaceSandbox::InNewPidNamespace())
        sandbox_status_flags_ |= kPIDNS;
      if (NamespaceSandbox::InNewNetNamespace())
        sandbox_status_flags_ |= kNetNS;
    }

    // We report whether the sandbox will be activated when renderers and
    // workers go through sandbox initialization.
    if (seccomp_bpf_supported()) {
      sandbox_status_flags_ |= kSeccompBPF;
    }

    if (seccomp_bpf_with_tsync_supported()) {
      sandbox_status_flags_ |= kSeccompTSYNC;
    }

    if (yama_is_enforcing_) {
      sandbox_status_flags_ |= kYama;
    }
  }

  return sandbox_status_flags_;
}

// Threads are counted via /proc/self/task. This is a little hairy because of
// PID namespaces and existing sandboxes, so "self" must really be used instead
// of using the pid.
bool SandboxLinux::IsSingleThreaded() const {
  base::ScopedFD proc_fd(OpenProc(proc_fd_));

  CHECK(proc_fd.is_valid()) << "Could not count threads, the sandbox was not "
                            << "pre-initialized properly.";

  const bool is_single_threaded =
      ThreadHelpers::IsSingleThreaded(proc_fd.get());

  return is_single_threaded;
}

bool SandboxLinux::seccomp_bpf_started() const {
  return seccomp_bpf_started_;
}

SetuidSandboxClient* SandboxLinux::setuid_sandbox_client() const {
  return setuid_sandbox_client_.get();
}

// For seccomp-bpf, we use the SandboxSeccompBPF class.
bool SandboxLinux::StartSeccompBPF(sandbox::mojom::Sandbox sandbox_type,
                                   PreSandboxHook hook,
                                   const Options& options) {
  CHECK(!seccomp_bpf_started_);
  CHECK(pre_initialized_);
#if BUILDFLAG(USE_SECCOMP_BPF)
  if (!seccomp_bpf_supported())
    return false;

  if (IsUnsandboxedSandboxType(sandbox_type) ||
      !SandboxSeccompBPF::IsSeccompBPFDesired() ||
      !SandboxSeccompBPF::SupportsSandbox()) {
    return true;
  }

  if (hook)
    CHECK(std::move(hook).Run(options));

  // If we allow threads *and* have multiple threads, try to use TSYNC.
  SandboxBPF::SeccompLevel seccomp_level =
      options.allow_threads_during_sandbox_init && !IsSingleThreaded()
          ? SandboxBPF::SeccompLevel::MULTI_THREADED
          : SandboxBPF::SeccompLevel::SINGLE_THREADED;

  // If the kernel supports the sandbox, and if the command line says we
  // should enable it, enable it or die.
  std::unique_ptr<BPFBasePolicy> policy =
      SandboxSeccompBPF::PolicyForSandboxType(sandbox_type, options);
  SandboxSeccompBPF::StartSandboxWithExternalPolicy(
      std::move(policy), OpenProc(proc_fd_), seccomp_level);
  SandboxSeccompBPF::RunSandboxSanityChecks(sandbox_type, options);
  seccomp_bpf_started_ = true;
  LogSandboxStarted("seccomp-bpf");
  return true;
#else
  return false;
#endif
}

bool SandboxLinux::InitializeSandbox(sandbox::mojom::Sandbox sandbox_type,
                                     SandboxLinux::PreSandboxHook hook,
                                     const Options& options) {
  DCHECK(!initialize_sandbox_ran_);
  initialize_sandbox_ran_ = true;

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  const std::string process_type =
      command_line->GetSwitchValueASCII(switches::kProcessType);

  // We need to make absolutely sure that our sandbox is "sealed" before
  // returning.
  absl::Cleanup sandbox_sealer = [this] { SealSandbox(); };
  // Make sure that this function enables sandboxes as promised by GetStatus().
  absl::Cleanup sandbox_promise_keeper = [this, sandbox_type] {
    CheckForBrokenPromises(sandbox_type);
  };

  const bool has_threads = !IsSingleThreaded();

  // For now, restrict the |options.allow_threads_during_sandbox_init| option to
  // the GPU process
  DCHECK(process_type == switches::kGpuProcess ||
         !options.allow_threads_during_sandbox_init);
  if (has_threads && !options.allow_threads_during_sandbox_init) {
    std::string error_message =
        "InitializeSandbox() called with multiple threads in process " +
        process_type + ".";
    // TSAN starts a helper thread, so we don't start the sandbox and don't
    // even report an error about it.
    if (IsRunningTSAN())
      return false;

    // Only a few specific processes are allowed to call InitializeSandbox()
    // with multiple threads running.
    bool sandbox_failure_fatal =
        !ShouldAllowThreadsDuringSandboxInit(process_type, sandbox_type);
    // This can be disabled with the '--gpu-sandbox-failures-fatal' flag.
    // Setting the flag with no value or any value different than 'yes' or 'no'
    // is equal to setting '--gpu-sandbox-failures-fatal=yes'.
    if (process_type == switches::kGpuProcess &&
        command_line->HasSwitch(switches::kGpuSandboxFailuresFatal)) {
      const std::string switch_value =
          command_line->GetSwitchValueASCII(switches::kGpuSandboxFailuresFatal);
      sandbox_failure_fatal = switch_value != "no";
    }

    if (sandbox_failure_fatal && !IsUnsandboxedSandboxType(sandbox_type)) {
      error_message += " Try waiting for /proc to be updated.";
      LOG(ERROR) << error_message;

      for (const auto& id :
           base::ThreadIdNameManager::GetInstance()->GetIds()) {
        LOG(ERROR) << "ThreadId=" << id << " name:"
                   << base::ThreadIdNameManager::GetInstance()->GetName(id);
      }
      // This will return if /proc/self eventually reports this process is
      // single-threaded, or crash if it does not after a number of retries.
      ThreadHelpers::AssertSingleThreaded();
    } else {
      LOG(WARNING) << error_message;
      return false;
    }
  }

  // At this point we are either single threaded, or we won't be engaging the
  // semantic layer of the sandbox and we won't care if there are file
  // descriptors left open.

  // Pre-initialize if not already done.
  if (!pre_initialized_)
    PreinitializeSandbox();

  // Turn on the namespace sandbox if our caller wants it (and the zygote hasn't
  // done so already).
  if (options.engage_namespace_sandbox)
    EngageNamespaceSandbox(false /* from_zygote */);

  // Check for open directories, which can break the semantic sandbox layer. In
  // some cases the caller doesn't want to enable the semantic sandbox layer,
  // and this CHECK should be skipped. In this case, the caller should unset
  // |options.check_for_open_directories|.
  CHECK(!options.check_for_open_directories || !HasOpenDirectories())
      << "InitializeSandbox() called after unexpected directories have been "
      << "opened. This breaks the security of the setuid sandbox.";

  InitLibcLocaltimeFunctions();

#if !BUILDFLAG(IS_CHROMEOS)
  if (!IsUnsandboxedSandboxType(sandbox_type)) {
    // No sandboxed process should make use of getaddrinfo() as it is impossible
    // to sandbox (e.g. glibc loads arbitrary third party DNS resolution
    // libraries).
    // On ChromeOS none of these third party libraries are installed, so there
    // is no need to discourage getaddrinfo().
    // TODO(crbug.com/40220505): in the future this should depend on the
    // libraries listed in /etc/nsswitch.conf, and should be a
    // SandboxLinux::Options option.
    DiscourageGetaddrinfo();
  }
#endif  // BUILDFLAG(IS_LINUX)

  // Attempt to limit the future size of the address space of the process.
  // Fine to call with multiple threads as we don't use RLIMIT_STACK.
  int error = 0;
  const bool limited_as = LimitAddressSpace(&error);
  if (error) {
    // Restore errno. Internally to |LimitAddressSpace|, the errno due to
    // setrlimit may be lost.
    errno = error;
    PCHECK(limited_as);
  }

  return StartSeccompBPF(sandbox_type, std::move(hook), options);
}

void SandboxLinux::StopThread(base::Thread* thread) {
  DCHECK(thread);
  StopThreadAndEnsureNotCounted(thread);
}

bool SandboxLinux::seccomp_bpf_supported() const {
  CHECK(pre_initialized_);
  return seccomp_bpf_supported_;
}

bool SandboxLinux::seccomp_bpf_with_tsync_supported() const {
  CHECK(pre_initialized_);
  return seccomp_bpf_with_tsync_supported_;
}

rlim_t GetProcessDataSizeLimit(sandbox::mojom::Sandbox sandbox_type) {
#if defined(ARCH_CPU_64_BITS)
  if (sandbox_type == sandbox::mojom::Sandbox::kGpu ||
      sandbox_type == sandbox::mojom::Sandbox::kOnDeviceModelExecution ||
      sandbox_type == sandbox::mojom::Sandbox::kRenderer) {
    // Allow the GPU/ODML/RENDERER process's sandbox to access more physical
    // memory if it's available on the system.
    //
    // Renderer processes are allowed to access 32 GB; the GPU/ODML processes,
    // up to 64 GB.
    constexpr rlim_t GB = 1024 * 1024 * 1024;
    const rlim_t physical_memory =
        base::SysInfo::AmountOfPhysicalMemory().InBytes();
    rlim_t limit;
    if ((sandbox_type == sandbox::mojom::Sandbox::kGpu ||
         sandbox_type == sandbox::mojom::Sandbox::kOnDeviceModelExecution) &&
        physical_memory > 64 * GB) {
      limit = 64 * GB;
    } else if (physical_memory > 32 * GB) {
      limit = 32 * GB;
    } else if (physical_memory > 16 * GB) {
      limit = 16 * GB;
    } else {
      limit = 8 * GB;
    }

    if (sandbox_type == sandbox::mojom::Sandbox::kRenderer &&
        base::FeatureList::IsEnabled(
            sandbox::policy::features::kHigherRendererMemoryLimit)) {
      limit *= 2;
    }

    return limit;
  }
#endif

  return static_cast<rlim_t>(kDataSizeLimit);
}

bool SandboxLinux::LimitAddressSpace(int* error) {
#if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \
    !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  sandbox::mojom::Sandbox sandbox_type =
      SandboxTypeFromCommandLine(*command_line);
  if (sandbox_type == sandbox::mojom::Sandbox::kNoSandbox) {
    return false;
  }

  // Unfortunately, it does not appear possible to set RLIMIT_AS such that it
  // will both (a) be high enough to support V8's and WebAssembly's address
  // space requirements while also (b) being low enough to mitigate exploits
  // using integer overflows that require large allocations, heap spray, or
  // other memory-hungry attack modes.

  rlim_t process_data_size_limit = GetProcessDataSizeLimit(sandbox_type);
  // Fine to call with multiple threads as we don't use RLIMIT_STACK.
  *error = ResourceLimits::Lower(RLIMIT_DATA, process_data_size_limit);

  // Cache the resource limit before turning on the sandbox.
  base::SysInfo::AmountOfVirtualMemory();

  return *error == 0;
#else
  base::SysInfo::AmountOfVirtualMemory();
  return false;
#endif  // !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) &&
        // !defined(THREAD_SANITIZER) && !defined(LEAK_SANITIZER)
}

void SandboxLinux::StartBrokerProcess(
    const syscall_broker::BrokerCommandSet& allowed_command_set,
    std::vector<syscall_broker::BrokerFilePermission> permissions,
    const Options& options) {
  // Use EACCES as the policy's default error number to remain consistent with
  // other LSMs like AppArmor and Landlock. Some userspace code, such as
  // glibc's |dlopen|, expect to see EACCES rather than EPERM. See
  // crbug.com/1233028 for an example.
  auto policy = std::make_optional<syscall_broker::BrokerSandboxConfig>(
      allowed_command_set, std::move(permissions), EACCES);
  // Leaked at shutdown, so use bare |new|.
  broker_process_ = new syscall_broker::BrokerProcess(
      std::move(policy),
      syscall_broker::BrokerProcess::BrokerType::SIGNAL_BASED);

  // The initialization callback will perform generic initialization and then
  // call broker_sandboxer_callback.
  CHECK(broker_process_->Fork(
      base::BindOnce(&UpdateProcessTypeAndEnableSandbox, options)));
}

bool SandboxLinux::ShouldBrokerHandleSyscall(int sysno) const {
  return broker_process_->IsSyscallAllowed(sysno);
}

bpf_dsl::ResultExpr SandboxLinux::HandleViaBroker(int sysno) const {
  const bpf_dsl::ResultExpr handle_via_broker =
      bpf_dsl::Trap(syscall_broker::BrokerClient::SIGSYS_Handler,
                    broker_process_->GetBrokerClientSignalBased());
  if (sysno == __NR_fstatat_default) {
    // This may be an fstatat(fd, "", stat_buf, AT_EMPTY_PATH), which should be
    // rewritten as fstat(fd, stat_buf). This should be consistent with how the
    // baseline policy handles fstatat().
    // Note that this will cause some legitimate but strange invocations of
    // fstatat() to fail, see https://crbug.com/1243290#c8 for details.
    const bpf_dsl::Arg<int> flags(3);
    return bpf_dsl::If((flags & AT_EMPTY_PATH) == AT_EMPTY_PATH,
                       RewriteFstatatSIGSYS(BPFBasePolicy::GetFSDeniedErrno()))
        .Else(handle_via_broker);
  } else {
    return handle_via_broker;
  }
}

bool SandboxLinux::HasOpenDirectories() const {
  return ProcUtil::HasOpenDirectory(proc_fd_);
}

void SandboxLinux::SealSandbox() {
  if (proc_fd_ >= 0) {
    int ret = IGNORE_EINTR(close(proc_fd_));
    CHECK_EQ(0, ret);
    proc_fd_ = -1;
  }
}

void SandboxLinux::CheckForBrokenPromises(
    sandbox::mojom::Sandbox sandbox_type) {
  if (sandbox_type != sandbox::mojom::Sandbox::kRenderer) {
    return;
  }
  // Make sure that any promise made with GetStatus() wasn't broken.
  bool promised_seccomp_bpf_would_start =
      (sandbox_status_flags_ != kInvalid) && (GetStatus() & kSeccompBPF);
  CHECK(!promised_seccomp_bpf_would_start || seccomp_bpf_started_);
}

void SandboxLinux::StopThreadAndEnsureNotCounted(base::Thread* thread) const {
  DCHECK(thread);
  base::ScopedFD proc_fd(OpenProc(proc_fd_));
  PCHECK(proc_fd.is_valid());
  CHECK(ThreadHelpers::StopThreadAndWatchProcFS(proc_fd.get(), thread));
}

bool SandboxLinux::EngageNamespaceSandboxInternal(bool from_zygote) {
  CHECK(pre_initialized_);
  CHECK(IsSingleThreaded())
      << "The process cannot have multiple threads when engaging the namespace "
         "sandbox, because the thread engaging the sandbox cannot ensure that "
         "other threads close all their open directories.";

  if (from_zygote) {
    // Check being in a new PID namespace created by the namespace sandbox and
    // being the init process.
    CHECK(NamespaceSandbox::InNewPidNamespace());
    const pid_t pid = getpid();
    CHECK_EQ(1, pid);
  }

  // After we successfully move to a new user ns, we don't allow this function
  // to fail.
  if (!Credentials::MoveToNewUserNS()) {
    return false;
  }

  // Note: this requires SealSandbox() to be called later in this process to be
  // safe, as this class is keeping a file descriptor to /proc/.
  CHECK(Credentials::DropFileSystemAccess(proc_fd_));

  // Now we drop all capabilities that we can. In the zygote process, we need
  // to keep CAP_SYS_ADMIN, to place each child in its own PID namespace
  // later on.
  std::vector<Credentials::Capability> caps;
  if (from_zygote) {
    caps.push_back(Credentials::Capability::SYS_ADMIN);
  }
  CHECK(Credentials::SetCapabilities(proc_fd_, caps));
  return true;
}

}  // namespace policy
}  // namespace sandbox
