Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320)
[chromium-blink-merge.git] / sandbox / linux / seccomp-bpf / sandbox_bpf.h
blob96cceb56480b7f6be4bfb158c4439d524c8a7318
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.
5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_
6 #define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_
8 #include <stdint.h>
10 #include "base/files/scoped_file.h"
11 #include "base/macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "sandbox/linux/bpf_dsl/codegen.h"
14 #include "sandbox/sandbox_export.h"
16 namespace sandbox {
17 struct arch_seccomp_data;
18 namespace bpf_dsl {
19 class Policy;
22 // This class can be used to apply a syscall sandboxing policy expressed in a
23 // bpf_dsl::Policy object to the current process.
24 // Syscall sandboxing policies get inherited by subprocesses and, once applied,
25 // can never be removed for the lifetime of the process.
26 class SANDBOX_EXPORT SandboxBPF {
27 public:
28 enum class SeccompLevel {
29 SINGLE_THREADED,
30 MULTI_THREADED,
33 // Ownership of |policy| is transfered here to the sandbox object.
34 // nullptr is allowed for unit tests.
35 explicit SandboxBPF(bpf_dsl::Policy* policy);
36 // NOTE: Setting a policy and starting the sandbox is a one-way operation.
37 // The kernel does not provide any option for unloading a loaded sandbox. The
38 // sandbox remains engaged even when the object is destructed.
39 ~SandboxBPF();
41 // Detect if the kernel supports the specified seccomp level.
42 // See StartSandbox() for a description of these.
43 static bool SupportsSeccompSandbox(SeccompLevel level);
45 // This is the main public entry point. It sets up the resources needed by
46 // the sandbox, and enters Seccomp mode.
47 // The calling process must provide a |level| to tell the sandbox which type
48 // of kernel support it should engage.
49 // SINGLE_THREADED will only sandbox the calling thread. Since it would be a
50 // security risk, the sandbox will also check that the current process is
51 // single threaded and crash if it isn't the case.
52 // MULTI_THREADED requires more recent kernel support and allows to sandbox
53 // all the threads of the current process. Be mindful of potential races,
54 // with other threads using disallowed system calls either before or after
55 // the sandbox is engaged.
57 // It is possible to stack multiple sandboxes by creating separate "Sandbox"
58 // objects and calling "StartSandbox()" on each of them. Please note, that
59 // this requires special care, though, as newly stacked sandboxes can never
60 // relax restrictions imposed by earlier sandboxes. Furthermore, installing
61 // a new policy requires making system calls, that might already be
62 // disallowed.
63 // Finally, stacking does add more kernel overhead than having a single
64 // combined policy. So, it should only be used if there are no alternatives.
65 bool StartSandbox(SeccompLevel level) WARN_UNUSED_RESULT;
67 // The sandbox needs to be able to access files in "/proc/self/". If
68 // this directory is not accessible when "StartSandbox()" gets called, the
69 // caller must provide an already opened file descriptor by calling
70 // "SetProcFd()".
71 // The sandbox becomes the new owner of this file descriptor and will
72 // close it when "StartSandbox()" executes or when the sandbox object
73 // disappears.
74 void SetProcFd(base::ScopedFD proc_fd);
76 // Checks whether a particular system call number is valid on the current
77 // architecture.
78 static bool IsValidSyscallNumber(int sysnum);
80 // UnsafeTraps require some syscalls to always be allowed.
81 // This helper function returns true for these calls.
82 static bool IsRequiredForUnsafeTrap(int sysno);
84 // From within an UnsafeTrap() it is often useful to be able to execute
85 // the system call that triggered the trap. The ForwardSyscall() method
86 // makes this easy. It is more efficient than calling glibc's syscall()
87 // function, as it avoid the extra round-trip to the signal handler. And
88 // it automatically does the correct thing to report kernel-style error
89 // conditions, rather than setting errno. See the comments for TrapFnc for
90 // details. In other words, the return value from ForwardSyscall() is
91 // directly suitable as a return value for a trap handler.
92 static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
94 // Assembles a BPF filter program from the current policy. After calling this
95 // function, you must not call any other sandboxing function.
96 // Typically, AssembleFilter() is only used by unit tests and by sandbox
97 // internals. It should not be used by production code.
98 // For performance reasons, we normally only run the assembled BPF program
99 // through the verifier, iff the program was built in debug mode.
100 // But by setting "force_verification", the caller can request that the
101 // verifier is run unconditionally. This is useful for unittests.
102 scoped_ptr<CodeGen::Program> AssembleFilter(bool force_verification);
104 private:
105 // Assembles and installs a filter based on the policy that has previously
106 // been configured with SetSandboxPolicy().
107 void InstallFilter(bool must_sync_threads);
109 base::ScopedFD proc_fd_;
110 bool sandbox_has_started_;
111 scoped_ptr<bpf_dsl::Policy> policy_;
113 DISALLOW_COPY_AND_ASSIGN(SandboxBPF);
116 } // namespace sandbox
118 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H_