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 18namespace 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. 28class 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