// Copyright 2015 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 "services/service_manager/public/cpp/standalone_service/sandbox_linux.h"

#include <fcntl.h>
#include <sys/syscall.h>
#include <utility>

#include "base/bind.h"
#include "base/debug/leak_annotations.h"
#include "base/macros.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
#include "base/sys_info.h"
#include "sandbox/linux/bpf_dsl/policy.h"
#include "sandbox/linux/bpf_dsl/trap_registry.h"
#include "sandbox/linux/seccomp-bpf-helpers/baseline_policy.h"
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
#include "sandbox/linux/services/credentials.h"
#include "sandbox/linux/services/namespace_sandbox.h"
#include "sandbox/linux/services/proc_util.h"
#include "sandbox/linux/services/thread_helpers.h"

using sandbox::syscall_broker::BrokerFilePermission;

namespace service_manager {
namespace deprecated {
namespace {

intptr_t SandboxSIGSYSHandler(const struct sandbox::arch_seccomp_data& args,
                              void* aux) {
  RAW_CHECK(aux);
  const sandbox::syscall_broker::BrokerProcess* broker_process =
      static_cast<const sandbox::syscall_broker::BrokerProcess*>(aux);
  switch (args.nr) {
#if !defined(__aarch64__)
    case __NR_access:
      return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
                                    static_cast<int>(args.args[1]));
    case __NR_open:
      return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
                                  static_cast<int>(args.args[1]));
#endif
    case __NR_faccessat:
      if (static_cast<int>(args.args[0]) == AT_FDCWD) {
        return broker_process->Access(
            reinterpret_cast<const char*>(args.args[1]),
            static_cast<int>(args.args[2]));
      } else {
        return -EPERM;
      }
    case __NR_openat:
      // Allow using openat() as open().
      if (static_cast<int>(args.args[0]) == AT_FDCWD) {
        return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
                                    static_cast<int>(args.args[2]));
      } else {
        return -EPERM;
      }
    default:
      RAW_CHECK(false);
      return -ENOSYS;
  }
}

class SandboxPolicy : public sandbox::BaselinePolicy {
 public:
  explicit SandboxPolicy(sandbox::syscall_broker::BrokerProcess* broker_process)
      : broker_process_(broker_process) {}
  ~SandboxPolicy() override {}

  // Overridden from sandbox::bpf_dsl::Policy:
  sandbox::bpf_dsl::ResultExpr EvaluateSyscall(int sysno) const override {
    // This policy is only advisory/for noticing FS access for the moment.
    switch (sysno) {
#if !defined(__aarch64__)
      case __NR_access:
      case __NR_open:
#endif
      case __NR_faccessat:
      case __NR_openat:
        return sandbox::bpf_dsl::Trap(SandboxSIGSYSHandler, broker_process_);
      case __NR_sched_getaffinity:
        return sandbox::RestrictSchedTarget(policy_pid(), sysno);
      case __NR_ftruncate:
#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
    defined(__aarch64__)
      // Per #ifdefs in
      // services/service_manager/sandbox/linux/bpf_renderer_policy_linux.cc
      case __NR_getrlimit:
#endif
#if defined(__i386__) || defined(__arm__)
      case __NR_ugetrlimit:
#endif
      case __NR_uname:
#if defined(__arm__) || defined(__x86_64__) || defined(__mips__)
      case __NR_getsockopt:
      case __NR_setsockopt:
#endif
        return sandbox::bpf_dsl::Allow();
    }

    return BaselinePolicy::EvaluateSyscall(sysno);
  }

 private:
  // Not owned.
  const sandbox::syscall_broker::BrokerProcess* broker_process_;
  DISALLOW_COPY_AND_ASSIGN(SandboxPolicy);
};

}  // namespace

SandboxLinux::SandboxLinux(const std::vector<BrokerFilePermission>& permissions)
    : broker_(new sandbox::syscall_broker::BrokerProcess(EPERM, permissions)) {
  CHECK(broker_->Init(
      base::Bind<bool (*)()>(&sandbox::Credentials::DropAllCapabilities)));
  policy_ = std::make_unique<SandboxPolicy>(broker_.get());
}

SandboxLinux::~SandboxLinux() {}

void SandboxLinux::Warmup() {
  proc_fd_ = sandbox::ProcUtil::OpenProc();
  warmed_up_ = true;

  // Verify that we haven't started threads or grabbed directory file
  // descriptors.
  sandbox::ThreadHelpers::AssertSingleThreaded(proc_fd_.get());
  CHECK(!sandbox::ProcUtil::HasOpenDirectory(proc_fd_.get()));
}

void SandboxLinux::EngageNamespaceSandbox() {
  CHECK(warmed_up_);
  CHECK_EQ(1, getpid());
  CHECK(sandbox::NamespaceSandbox::InNewPidNamespace());
  CHECK(sandbox::Credentials::MoveToNewUserNS());
  CHECK(sandbox::Credentials::DropFileSystemAccess(proc_fd_.get()));
  CHECK(sandbox::Credentials::DropAllCapabilities(proc_fd_.get()));
}

void SandboxLinux::EngageSeccompSandbox() {
  CHECK(warmed_up_);
  sandbox::SandboxBPF sandbox(std::move(policy_));
  base::ScopedFD proc_fd(HANDLE_EINTR(
      openat(proc_fd_.get(), ".", O_RDONLY | O_DIRECTORY | O_CLOEXEC)));
  CHECK(proc_fd.is_valid());
  sandbox.SetProcFd(std::move(proc_fd));
  CHECK(
      sandbox.StartSandbox(sandbox::SandboxBPF::SeccompLevel::SINGLE_THREADED))
      << "Starting the process with a sandbox failed. Missing kernel support.";

  // The Broker is now bound to this process and should only be destroyed when
  // the process exits or is killed.
  sandbox::syscall_broker::BrokerProcess* leaked_broker = broker_.release();
  ALLOW_UNUSED_LOCAL(leaked_broker);
  ANNOTATE_LEAKING_OBJECT_PTR(leaked_broker);
}

void SandboxLinux::Seal() {
  proc_fd_.reset();
}

}  // namespace deprecated
}  // namespace service_manager
