// 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 "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.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_;
  scoped_ptr<bpf_dsl::Policy> policy_;

  DISALLOW_COPY_AND_ASSIGN(SandboxBPF);
};

}  // namespace sandbox

#endif  // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_
