// 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_TRAP_H__
#define SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__

#include <stdint.h>

#include <map>

#include "base/macros.h"
#include "sandbox/linux/bpf_dsl/trap_registry.h"
#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/sandbox_export.h"

namespace sandbox {

// The Trap class allows a BPF filter program to branch out to user space by
// raising a SIGSYS signal.
// N.B.: This class does not perform any synchronization operations. If
//   modifications are made to any of the traps, it is the caller's
//   responsibility to ensure that this happens in a thread-safe fashion.
//   Preferably, that means that no other threads should be running at that
//   time. For the purposes of our sandbox, this assertion should always be
//   true. Threads are incompatible with the seccomp sandbox anyway.
class SANDBOX_EXPORT Trap : public bpf_dsl::TrapRegistry {
 public:
  uint16_t Add(TrapFnc fnc, const void* aux, bool safe) override;

  bool EnableUnsafeTraps() override;

  // Registry returns the trap registry used by Trap's SIGSYS handler,
  // creating it if necessary.
  static bpf_dsl::TrapRegistry* Registry();

  // SandboxDebuggingAllowedByUser returns whether the
  // "CHROME_SANDBOX_DEBUGGING" environment variable is set.
  static bool SandboxDebuggingAllowedByUser();

 private:
  struct TrapKey {
    TrapKey() : fnc(NULL), aux(NULL), safe(false) {}
    TrapKey(TrapFnc f, const void* a, bool s) : fnc(f), aux(a), safe(s) {}
    TrapFnc fnc;
    const void* aux;
    bool safe;
    bool operator<(const TrapKey&) const;
  };
  typedef std::map<TrapKey, uint16_t> TrapIds;

  // Our constructor is private. A shared global instance is created
  // automatically as needed.
  Trap();

  // The destructor is unimplemented as destroying this object would
  // break subsequent system calls that trigger a SIGSYS.
  ~Trap() = delete;

  static void SigSysAction(int nr, LinuxSigInfo* info, void* void_context);

  // Make sure that SigSys is not inlined in order to get slightly better crash
  // dumps.
  void SigSys(int nr, LinuxSigInfo* info, ucontext_t* ctx)
      __attribute__((noinline));
  // We have a global singleton that handles all of our SIGSYS traps. This
  // variable must never be deallocated after it has been set up initially, as
  // there is no way to reset in-kernel BPF filters that generate SIGSYS
  // events.
  static Trap* global_trap_;

  TrapIds trap_ids_;            // Maps from TrapKeys to numeric ids
  TrapKey* trap_array_;         // Array of TrapKeys indexed by ids
  size_t trap_array_size_;      // Currently used size of array
  size_t trap_array_capacity_;  // Currently allocated capacity of array
  bool has_unsafe_traps_;       // Whether unsafe traps have been enabled

  // Copying and assigning is unimplemented. It doesn't make sense for a
  // singleton.
  DISALLOW_COPY_AND_ASSIGN(Trap);
};

}  // namespace sandbox

#endif  // SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
