159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Copyright 2014 The Chromium Authors. All rights reserved.
259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Use of this source code is governed by a BSD-style license that can be
359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// found in the LICENSE file.
459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#ifndef SANDBOX_LINUX_BPF_DSL_TRAP_REGISTRY_H_
659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define SANDBOX_LINUX_BPF_DSL_TRAP_REGISTRY_H_
759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include <stdint.h>
959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "base/macros.h"
1159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/sandbox_export.h"
1259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace sandbox {
1459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This must match the kernel's seccomp_data structure.
1659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstruct arch_seccomp_data {
1759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  int nr;
1859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  uint32_t arch;
1959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  uint64_t instruction_pointer;
2059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  uint64_t args[6];
2159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
2259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
2359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace bpf_dsl {
2459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
2559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// TrapRegistry provides an interface for registering "trap handlers"
2659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// by associating them with non-zero 16-bit trap IDs. Trap IDs should
2759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// remain valid for the lifetime of the trap registry.
2859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass SANDBOX_EXPORT TrapRegistry {
2959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
3059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // TrapFnc is a pointer to a function that fulfills the trap handler
3159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // function signature.
3259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  //
3359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Trap handlers follow the calling convention of native system
3459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // calls; e.g., to report an error, they return an exit code in the
3559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // range -1..-4096 instead of directly modifying errno. However,
3659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // modifying errno is harmless, as the original value will be
3759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // restored afterwards.
3859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  //
3959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Trap handlers are executed from signal context and possibly an
4059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // async-signal context, so they must be async-signal safe:
4159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
4259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void* aux);
4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Add registers the specified trap handler tuple and returns a
4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // non-zero trap ID that uniquely identifies the tuple for the life
4659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // time of the trap registry. If the same tuple is registered
4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // multiple times, the same value will be returned each time.
4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  virtual uint16_t Add(TrapFnc fnc, const void* aux, bool safe) = 0;
4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // EnableUnsafeTraps tries to enable unsafe traps and returns
5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // whether it was successful. This is a one-way operation.
5259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  //
5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // CAUTION: Enabling unsafe traps effectively defeats the security
5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // guarantees provided by the sandbox policy. TrapRegistry
5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // implementations should ensure unsafe traps are only enabled
5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // during testing.
5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  virtual bool EnableUnsafeTraps() = 0;
5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat protected:
6059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  TrapRegistry() {}
6159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
6259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // TrapRegistry's destructor is intentionally non-virtual so that
6359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // implementations can omit their destructor.  Instead we protect against
6459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // misuse by marking it protected.
6559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ~TrapRegistry() {}
6659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  DISALLOW_COPY_AND_ASSIGN(TrapRegistry);
6859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
6959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}  // namespace bpf_dsl
7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}  // namespace sandbox
7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
7359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif  // SANDBOX_LINUX_BPF_DSL_TRAP_REGISTRY_H_
74