// Copyright (c) 2012 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_SECCOMP_BPF_SANDBOX_BPF_H_
#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_

#include <stdint.h>

#include <memory>

#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "sandbox/linux/bpf_dsl/codegen.h"
#include "sandbox/sandbox_export.h"

namespace sandbox {
struct arch_seccomp_data;
namespace bpf_dsl {
class Policy;
}

// This class can be used to apply a syscall sandboxing policy expressed in a
// bpf_dsl::Policy object to the current process.
// Syscall sandboxing policies get inherited by subprocesses and, once applied,
// can never be removed for the lifetime of the process.
class SANDBOX_EXPORT SandboxBPF {
 public:
  enum class SeccompLevel {
    SINGLE_THREADED,
    MULTI_THREADED,
  };

  // Ownership of |policy| is transfered here to the sandbox object.
  // nullptr is allowed for unit tests.
  explicit SandboxBPF(bpf_dsl::Policy* policy);
  // NOTE: Setting a policy and starting the sandbox is a one-way operation.
  // The kernel does not provide any option for unloading a loaded sandbox. The
  // sandbox remains engaged even when the object is destructed.
  ~SandboxBPF();

  // Detect if the kernel supports the specified seccomp level.
  // See StartSandbox() for a description of these.
  static bool SupportsSeccompSandbox(SeccompLevel level);

  // This is the main public entry point. It sets up the resources needed by
  // the sandbox, and enters Seccomp mode.
  // The calling process must provide a |level| to tell the sandbox which type
  // of kernel support it should engage.
  // SINGLE_THREADED will only sandbox the calling thread. Since it would be a
  // security risk, the sandbox will also check that the current process is
  // single threaded and crash if it isn't the case.
  // MULTI_THREADED requires more recent kernel support and allows to sandbox
  // all the threads of the current process. Be mindful of potential races,
  // with other threads using disallowed system calls either before or after
  // the sandbox is engaged.
  //
  // It is possible to stack multiple sandboxes by creating separate "Sandbox"
  // objects and calling "StartSandbox()" on each of them. Please note, that
  // this requires special care, though, as newly stacked sandboxes can never
  // relax restrictions imposed by earlier sandboxes. Furthermore, installing
  // a new policy requires making system calls, that might already be
  // disallowed.
  // Finally, stacking does add more kernel overhead than having a single
  // combined policy. So, it should only be used if there are no alternatives.
  bool StartSandbox(SeccompLevel level) WARN_UNUSED_RESULT;

  // The sandbox needs to be able to access files in "/proc/self/". If
  // this directory is not accessible when "StartSandbox()" gets called, the
  // caller must provide an already opened file descriptor by calling
  // "SetProcFd()".
  // The sandbox becomes the new owner of this file descriptor and will
  // close it when "StartSandbox()" executes or when the sandbox object
  // disappears.
  void SetProcFd(base::ScopedFD proc_fd);

  // Checks whether a particular system call number is valid on the current
  // architecture.
  static bool IsValidSyscallNumber(int sysnum);

  // UnsafeTraps require some syscalls to always be allowed.
  // This helper function returns true for these calls.
  static bool IsRequiredForUnsafeTrap(int sysno);

  // From within an UnsafeTrap() it is often useful to be able to execute
  // the system call that triggered the trap. The ForwardSyscall() method
  // makes this easy. It is more efficient than calling glibc's syscall()
  // function, as it avoid the extra round-trip to the signal handler. And
  // it automatically does the correct thing to report kernel-style error
  // conditions, rather than setting errno. See the comments for TrapFnc for
  // details. In other words, the return value from ForwardSyscall() is
  // directly suitable as a return value for a trap handler.
  static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);

 private:
  friend class SandboxBPFTestRunner;

  // Assembles a BPF filter program from the current policy. After calling this
  // function, you must not call any other sandboxing function.
  CodeGen::Program AssembleFilter();

  // Assembles and installs a filter based on the policy that has previously
  // been configured with SetSandboxPolicy().
  void InstallFilter(bool must_sync_threads);

  base::ScopedFD proc_fd_;
  bool sandbox_has_started_;
  std::unique_ptr<bpf_dsl::Policy> policy_;

  DISALLOW_COPY_AND_ASSIGN(SandboxBPF);
};

}  // namespace sandbox

#endif  // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_
