Home | History | Annotate | Download | only in seccomp-bpf
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
      6 #define SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <map>
     12 
     13 #include "base/macros.h"
     14 #include "sandbox/linux/bpf_dsl/trap_registry.h"
     15 #include "sandbox/linux/system_headers/linux_signal.h"
     16 #include "sandbox/sandbox_export.h"
     17 
     18 namespace sandbox {
     19 
     20 // The Trap class allows a BPF filter program to branch out to user space by
     21 // raising a SIGSYS signal.
     22 // N.B.: This class does not perform any synchronization operations. If
     23 //   modifications are made to any of the traps, it is the caller's
     24 //   responsibility to ensure that this happens in a thread-safe fashion.
     25 //   Preferably, that means that no other threads should be running at that
     26 //   time. For the purposes of our sandbox, this assertion should always be
     27 //   true. Threads are incompatible with the seccomp sandbox anyway.
     28 class SANDBOX_EXPORT Trap : public bpf_dsl::TrapRegistry {
     29  public:
     30   uint16_t Add(TrapFnc fnc, const void* aux, bool safe) override;
     31 
     32   bool EnableUnsafeTraps() override;
     33 
     34   // Registry returns the trap registry used by Trap's SIGSYS handler,
     35   // creating it if necessary.
     36   static bpf_dsl::TrapRegistry* Registry();
     37 
     38   // SandboxDebuggingAllowedByUser returns whether the
     39   // "CHROME_SANDBOX_DEBUGGING" environment variable is set.
     40   static bool SandboxDebuggingAllowedByUser();
     41 
     42  private:
     43   struct TrapKey {
     44     TrapKey() : fnc(NULL), aux(NULL), safe(false) {}
     45     TrapKey(TrapFnc f, const void* a, bool s) : fnc(f), aux(a), safe(s) {}
     46     TrapFnc fnc;
     47     const void* aux;
     48     bool safe;
     49     bool operator<(const TrapKey&) const;
     50   };
     51   typedef std::map<TrapKey, uint16_t> TrapIds;
     52 
     53   // Our constructor is private. A shared global instance is created
     54   // automatically as needed.
     55   Trap();
     56 
     57   // The destructor is unimplemented as destroying this object would
     58   // break subsequent system calls that trigger a SIGSYS.
     59   ~Trap() = delete;
     60 
     61   static void SigSysAction(int nr, LinuxSigInfo* info, void* void_context);
     62 
     63   // Make sure that SigSys is not inlined in order to get slightly better crash
     64   // dumps.
     65   void SigSys(int nr, LinuxSigInfo* info, ucontext_t* ctx)
     66       __attribute__((noinline));
     67   // We have a global singleton that handles all of our SIGSYS traps. This
     68   // variable must never be deallocated after it has been set up initially, as
     69   // there is no way to reset in-kernel BPF filters that generate SIGSYS
     70   // events.
     71   static Trap* global_trap_;
     72 
     73   TrapIds trap_ids_;            // Maps from TrapKeys to numeric ids
     74   TrapKey* trap_array_;         // Array of TrapKeys indexed by ids
     75   size_t trap_array_size_;      // Currently used size of array
     76   size_t trap_array_capacity_;  // Currently allocated capacity of array
     77   bool has_unsafe_traps_;       // Whether unsafe traps have been enabled
     78 
     79   // Copying and assigning is unimplemented. It doesn't make sense for a
     80   // singleton.
     81   DISALLOW_COPY_AND_ASSIGN(Trap);
     82 };
     83 
     84 }  // namespace sandbox
     85 
     86 #endif  // SANDBOX_LINUX_SECCOMP_BPF_TRAP_H__
     87