Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.h

Issue 11411254: SECCOMP-BPF: Added supported for inspection system call arguments from BPF filters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments and fixed death tests Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 5 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
6 #define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 6 #define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
7 7
8 #include <endian.h> 8 #include <endian.h>
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 19 matching lines...) Expand all
30 #include <sys/stat.h> 30 #include <sys/stat.h>
31 #include <sys/types.h> 31 #include <sys/types.h>
32 #include <sys/uio.h> 32 #include <sys/uio.h>
33 #include <sys/wait.h> 33 #include <sys/wait.h>
34 #include <time.h> 34 #include <time.h>
35 #include <unistd.h> 35 #include <unistd.h>
36 36
37 #include <algorithm> 37 #include <algorithm>
38 #include <limits> 38 #include <limits>
39 #include <map> 39 #include <map>
40 #include <set>
40 #include <utility> 41 #include <utility>
41 #include <vector> 42 #include <vector>
42 43
43 #ifndef SECCOMP_BPF_STANDALONE 44 #if !defined(SECCOMP_BPF_STANDALONE)
44 #include "base/basictypes.h" 45 #include "base/basictypes.h"
45 #include "base/logging.h" 46 #include "base/logging.h"
46 #include "base/posix/eintr_wrapper.h" 47 #include "base/posix/eintr_wrapper.h"
47 #endif 48 #endif
48 49
49 #if defined(SECCOMP_BPF_VALGRIND_HACKS) 50 #if defined(SECCOMP_BPF_VALGRIND_HACKS)
50 #ifndef SECCOMP_BPF_STANDALONE 51 #if !defined(SECCOMP_BPF_STANDALONE)
51 #include "base/third_party/valgrind/valgrind.h" 52 #include "base/third_party/valgrind/valgrind.h"
52 #endif 53 #endif
53 #endif 54 #endif
54 55
55 56
56 // The Seccomp2 kernel ABI is not part of older versions of glibc. 57 // The Seccomp2 kernel ABI is not part of older versions of glibc.
57 // As we can't break compilation with these versions of the library, 58 // As we can't break compilation with these versions of the library,
58 // we explicitly define all missing symbols. 59 // we explicitly define all missing symbols.
59 60
60 #ifndef PR_SET_NO_NEW_PRIVS 61 #ifndef PR_SET_NO_NEW_PRIVS
61 #define PR_SET_NO_NEW_PRIVS 38 62 #define PR_SET_NO_NEW_PRIVS 38
62 #define PR_GET_NO_NEW_PRIVS 39 63 #define PR_GET_NO_NEW_PRIVS 39
63 #endif 64 #endif
64 #ifndef IPC_64 65 #ifndef IPC_64
65 #define IPC_64 0x0100 66 #define IPC_64 0x0100
66 #endif 67 #endif
68
69 // In order to build will older tool chains, we currently have to avoid
70 // including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on
71 // our own definitions of the seccomp kernel ABI.
67 #ifndef SECCOMP_MODE_FILTER 72 #ifndef SECCOMP_MODE_FILTER
68 #define SECCOMP_MODE_DISABLED 0 73 #define SECCOMP_MODE_DISABLED 0
69 #define SECCOMP_MODE_STRICT 1 74 #define SECCOMP_MODE_STRICT 1
70 #define SECCOMP_MODE_FILTER 2 // User user-supplied filter 75 #define SECCOMP_MODE_FILTER 2 // User user-supplied filter
76 #endif
77
78 #ifndef SECCOMP_RET_KILL
79 // Return values supported for BPF filter programs. Please note that the
80 // "illegal" SECCOMP_RET_INVALID is not supported by the kernel, should only
81 // ever be used internally, and would result in the kernel killing our process.
71 #define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately 82 #define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately
83 #define SECCOMP_RET_INVALID 0x00010000U // Illegal return value
72 #define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS 84 #define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS
73 #define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno 85 #define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno
74 #define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow 86 #define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow
75 #define SECCOMP_RET_ALLOW 0x7fff0000U // Allow 87 #define SECCOMP_RET_ALLOW 0x7fff0000U // Allow
76 #define SECCOMP_RET_INVALID 0x8f8f8f8fU // Illegal return value
77 #define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value 88 #define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value
78 #define SECCOMP_RET_DATA 0x0000ffffU // sections 89 #define SECCOMP_RET_DATA 0x0000ffffU // sections
90 #else
91 #define SECCOMP_RET_INVALID 0x00010000U // Illegal return value
79 #endif 92 #endif
80 #define SECCOMP_DENY_ERRNO EPERM 93
81 #ifndef SYS_SECCOMP 94 #ifndef SYS_SECCOMP
82 #define SYS_SECCOMP 1 95 #define SYS_SECCOMP 1
83 #endif 96 #endif
84 97
85 // Impose some reasonable maximum BPF program size. Realistically, the 98 // Impose some reasonable maximum BPF program size. Realistically, the
86 // kernel probably has much lower limits. But by limiting to less than 99 // kernel probably has much lower limits. But by limiting to less than
87 // 30 bits, we can ease requirements on some of our data types. 100 // 30 bits, we can ease requirements on some of our data types.
88 #define SECCOMP_MAX_PROGRAM_SIZE (1<<30) 101 #define SECCOMP_MAX_PROGRAM_SIZE (1<<30)
89 102
90 #if defined(__i386__) 103 #if defined(__i386__)
91 #define MIN_SYSCALL 0u 104 #define MIN_SYSCALL 0u
92 #define MAX_PUBLIC_SYSCALL 1024u 105 #define MAX_PUBLIC_SYSCALL 1024u
93 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL 106 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL
94 #define SECCOMP_ARCH AUDIT_ARCH_I386 107 #define SECCOMP_ARCH AUDIT_ARCH_I386
95 108
96 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 109 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
97 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) 110 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX)
98 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) 111 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX)
99 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) 112 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP)
100 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) 113 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX)
101 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) 114 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX)
102 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) 115 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX)
103 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) 116 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI)
104 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) 117 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI)
105 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) 118 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP)
119 #define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
120 #define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
121 #define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
122 instruction_pointer) + 4)
123 #define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
124 instruction_pointer) + 0)
125 #define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
126 8*(nr) + 4)
127 #define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
128 8*(nr) + 0)
106 129
107 #elif defined(__x86_64__) 130 #elif defined(__x86_64__)
108 #define MIN_SYSCALL 0u 131 #define MIN_SYSCALL 0u
109 #define MAX_PUBLIC_SYSCALL 1024u 132 #define MAX_PUBLIC_SYSCALL 1024u
110 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL 133 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL
111 #define SECCOMP_ARCH AUDIT_ARCH_X86_64 134 #define SECCOMP_ARCH AUDIT_ARCH_X86_64
112 135
113 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 136 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
114 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) 137 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX)
115 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) 138 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX)
116 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) 139 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP)
117 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) 140 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI)
118 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) 141 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI)
119 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) 142 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX)
120 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) 143 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10)
121 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) 144 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8)
122 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) 145 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9)
146 #define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
147 #define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
148 #define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
149 instruction_pointer) + 4)
150 #define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
151 instruction_pointer) + 0)
152 #define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
153 8*(nr) + 4)
154 #define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
155 8*(nr) + 0)
123 156
124 #elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) 157 #elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))
125 // ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, 158 // ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|,
126 // and a "ghost syscall private to the kernel", cmpxchg, 159 // and a "ghost syscall private to the kernel", cmpxchg,
127 // at |__ARM_NR_BASE+0x00fff0|. 160 // at |__ARM_NR_BASE+0x00fff0|.
128 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. 161 // See </arch/arm/include/asm/unistd.h> in the Linux kernel.
129 #define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE) 162 #define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE)
130 #define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u) 163 #define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u)
131 #define MIN_PRIVATE_SYSCALL ((unsigned int)__ARM_NR_BASE) 164 #define MIN_PRIVATE_SYSCALL ((unsigned int)__ARM_NR_BASE)
132 #define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u) 165 #define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u)
133 #define MIN_GHOST_SYSCALL ((unsigned int)__ARM_NR_BASE + 0xfff0u) 166 #define MIN_GHOST_SYSCALL ((unsigned int)__ARM_NR_BASE + 0xfff0u)
134 #define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u) 167 #define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u)
135 // <linux/audit.h> includes <linux/elf-em.h>, which does not define EM_ARM. 168 // <linux/audit.h> includes <linux/elf-em.h>, which does not define EM_ARM.
136 // <linux/elf.h> only includes <asm/elf.h> if we're in the kernel. 169 // <linux/elf.h> only includes <asm/elf.h> if we're in the kernel.
137 # if !defined(EM_ARM) 170 # if !defined(EM_ARM)
138 # define EM_ARM 40 171 # define EM_ARM 40
139 # endif 172 # endif
140 #define SECCOMP_ARCH AUDIT_ARCH_ARM 173 #define SECCOMP_ARCH AUDIT_ARCH_ARM
141 174
142 // ARM sigcontext_t is different from i386/x86_64. 175 // ARM sigcontext_t is different from i386/x86_64.
143 // See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. 176 // See </arch/arm/include/asm/sigcontext.h> in the Linux kernel.
144 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) 177 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg)
145 // ARM EABI syscall convention. 178 // ARM EABI syscall convention.
146 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) 179 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0)
147 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) 180 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7)
148 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) 181 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc)
149 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) 182 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0)
150 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) 183 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1)
151 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) 184 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2)
152 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) 185 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3)
153 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) 186 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4)
154 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) 187 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5)
188 #define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr))
189 #define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch))
190 #define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \
191 instruction_pointer) + 4)
192 #define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \
193 instruction_pointer) + 0)
194 #define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
195 8*(nr) + 4)
196 #define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \
197 8*(nr) + 0)
155 198
156 #else 199 #else
157 #error Unsupported target platform 200 #error Unsupported target platform
158 201
159 #endif 202 #endif
160 203
161 #if defined(SECCOMP_BPF_STANDALONE) 204 #if defined(SECCOMP_BPF_STANDALONE)
162 #define arraysize(x) (sizeof(x)/sizeof(*(x))) 205 #define arraysize(x) (sizeof(x)/sizeof(*(x)))
163 #define HANDLE_EINTR TEMP_FAILURE_RETRY 206 #define HANDLE_EINTR TEMP_FAILURE_RETRY
164 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 207 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // Please note that TrapFnc is executed from signal context and must be 256 // Please note that TrapFnc is executed from signal context and must be
214 // async-signal safe: 257 // async-signal safe:
215 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html 258 // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
216 // Also note that it follows the calling convention of native system calls. 259 // Also note that it follows the calling convention of native system calls.
217 // In other words, it reports an error by returning an exit code in the 260 // In other words, it reports an error by returning an exit code in the
218 // range -1..-4096. It should not set errno when reporting errors; on the 261 // range -1..-4096. It should not set errno when reporting errors; on the
219 // other hand, accidentally modifying errno is harmless and the changes will 262 // other hand, accidentally modifying errno is harmless and the changes will
220 // be undone afterwards. 263 // be undone afterwards.
221 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux); 264 typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
222 265
223 enum Operation {
224 OP_NOP, OP_EQUAL, OP_NOTEQUAL, OP_LESS,
225 OP_LESS_EQUAL, OP_GREATER, OP_GREATER_EQUAL,
226 OP_HAS_BITS, OP_DOES_NOT_HAVE_BITS
227 };
228
229 struct Constraint {
230 bool is32bit;
231 Operation op;
232 uint32_t value;
233 ErrorCode passed;
234 ErrorCode failed;
235 };
236
237 // When calling setSandboxPolicy(), the caller can provide an arbitrary 266 // When calling setSandboxPolicy(), the caller can provide an arbitrary
238 // pointer. This pointer will then be forwarded to the sandbox policy 267 // pointer. This pointer will then be forwarded to the sandbox policy
239 // each time a call is made through an EvaluateSyscall function pointer. 268 // each time a call is made through an EvaluateSyscall function pointer.
240 // One common use case would be to pass the "aux" pointer as an argument 269 // One common use case would be to pass the "aux" pointer as an argument
241 // to Trap() functions. 270 // to Trap() functions.
242 typedef ErrorCode (*EvaluateSyscall)(int sysnum, void *aux); 271 typedef ErrorCode (*EvaluateSyscall)(int sysnum, void *aux);
243 typedef std::vector<std::pair<EvaluateSyscall, void *> >Evaluators; 272 typedef std::vector<std::pair<EvaluateSyscall, void *> >Evaluators;
244 273
245 // Checks whether a particular system call number is valid on the current 274 // Checks whether a particular system call number is valid on the current
246 // architecture. E.g. on ARM there's a non-contiguous range of private 275 // architecture. E.g. on ARM there's a non-contiguous range of private
247 // system calls. 276 // system calls.
248 static bool isValidSyscallNumber(int sysnum); 277 static bool IsValidSyscallNumber(int sysnum);
249 278
250 // There are a lot of reasons why the Seccomp sandbox might not be available. 279 // There are a lot of reasons why the Seccomp sandbox might not be available.
251 // This could be because the kernel does not support Seccomp mode, or it 280 // This could be because the kernel does not support Seccomp mode, or it
252 // could be because another sandbox is already active. 281 // could be because another sandbox is already active.
253 // "proc_fd" should be a file descriptor for "/proc", or -1 if not 282 // "proc_fd" should be a file descriptor for "/proc", or -1 if not
254 // provided by the caller. 283 // provided by the caller.
255 static SandboxStatus supportsSeccompSandbox(int proc_fd); 284 static SandboxStatus SupportsSeccompSandbox(int proc_fd);
256 285
257 // The sandbox needs to be able to access files in "/proc/self". If this 286 // The sandbox needs to be able to access files in "/proc/self". If this
258 // directory is not accessible when "startSandbox()" gets called, the caller 287 // directory is not accessible when "startSandbox()" gets called, the caller
259 // can provide an already opened file descriptor by calling "setProcFd()". 288 // can provide an already opened file descriptor by calling "setProcFd()".
260 // The sandbox becomes the new owner of this file descriptor and will 289 // The sandbox becomes the new owner of this file descriptor and will
261 // eventually close it when "startSandbox()" executes. 290 // eventually close it when "startSandbox()" executes.
262 static void setProcFd(int proc_fd); 291 static void SetProcFd(int proc_fd);
263 292
264 // The system call evaluator function is called with the system 293 // The system call evaluator function is called with the system
265 // call number. It can decide to allow the system call unconditionally 294 // call number. It can decide to allow the system call unconditionally
266 // by returning ERR_ALLOWED; it can deny the system call unconditionally by 295 // by returning ERR_ALLOWED; it can deny the system call unconditionally by
267 // returning an appropriate "errno" value; or it can request inspection 296 // returning an appropriate "errno" value; or it can request inspection
268 // of system call argument(s) by returning a suitable ErrorCode. 297 // of system call argument(s) by returning a suitable ErrorCode.
269 // The "aux" parameter can be used to pass optional data to the system call 298 // The "aux" parameter can be used to pass optional data to the system call
270 // evaluator. There are different possible uses for this data, but one of the 299 // evaluator. There are different possible uses for this data, but one of the
271 // use cases would be for the policy to then forward this pointer to a Trap() 300 // use cases would be for the policy to then forward this pointer to a Trap()
272 // handler. In this case, of course, the data that is pointed to must remain 301 // handler. In this case, of course, the data that is pointed to must remain
273 // valid for the entire time that Trap() handlers can be called; typically, 302 // valid for the entire time that Trap() handlers can be called; typically,
274 // this would be the lifetime of the program. 303 // this would be the lifetime of the program.
275 static void setSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux); 304 static void SetSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
276 305
277 // We can use ErrorCode to request calling of a trap handler. This method 306 // We can use ErrorCode to request calling of a trap handler. This method
278 // performs the required wrapping of the callback function into an 307 // performs the required wrapping of the callback function into an
279 // ErrorCode object. 308 // ErrorCode object.
280 // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall 309 // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall
281 // for a description of how to pass data from setSandboxPolicy() to a Trap() 310 // for a description of how to pass data from setSandboxPolicy() to a Trap()
282 // handler. 311 // handler.
283 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux); 312 static ErrorCode Trap(ErrorCode::TrapFnc fnc, const void *aux);
284 313
285 // Calls a user-space trap handler and disables all sandboxing for system 314 // Calls a user-space trap handler and disables all sandboxing for system
286 // calls made from this trap handler. 315 // calls made from this trap handler.
287 // NOTE: This feature, by definition, disables all security features of 316 // NOTE: This feature, by definition, disables all security features of
288 // the sandbox. It should never be used in production, but it can be 317 // the sandbox. It should never be used in production, but it can be
289 // very useful to diagnose code that is incompatible with the sandbox. 318 // very useful to diagnose code that is incompatible with the sandbox.
290 // If even a single system call returns "UnsafeTrap", the security of 319 // If even a single system call returns "UnsafeTrap", the security of
291 // entire sandbox should be considered compromised. 320 // entire sandbox should be considered compromised.
292 static ErrorCode UnsafeTrap(ErrorCode::TrapFnc fnc, const void *aux); 321 static ErrorCode UnsafeTrap(ErrorCode::TrapFnc fnc, const void *aux);
293 322
294 // From within an UnsafeTrap() it is often useful to be able to execute 323 // From within an UnsafeTrap() it is often useful to be able to execute
295 // the system call that triggered the trap. The ForwardSyscall() method 324 // the system call that triggered the trap. The ForwardSyscall() method
296 // makes this easy. It is more efficient than calling glibc's syscall() 325 // makes this easy. It is more efficient than calling glibc's syscall()
297 // function, as it avoid the extra round-trip to the signal handler. And 326 // function, as it avoid the extra round-trip to the signal handler. And
298 // it automatically does the correct thing to report kernel-style error 327 // it automatically does the correct thing to report kernel-style error
299 // conditions, rather than setting errno. See the comments for TrapFnc for 328 // conditions, rather than setting errno. See the comments for TrapFnc for
300 // details. In other words, the return value from ForwardSyscall() is 329 // details. In other words, the return value from ForwardSyscall() is
301 // directly suitable as a return value for a trap handler. 330 // directly suitable as a return value for a trap handler.
302 static intptr_t ForwardSyscall(const struct arch_seccomp_data& args); 331 static intptr_t ForwardSyscall(const struct arch_seccomp_data& args);
303 332
333 // We can also use ErrorCode to request evaluation of a conditional
334 // statement based on inspection of system call parameters.
335 // This method wrap an ErrorCode object around the conditional statement.
336 // Argument "argno" (1..6) will be compared to "value" using comparator
337 // "op". If the condition is true "passed" will be returned, otherwise
338 // "failed".
339 // If "is32bit" is set, the argument must in the range of 0x0..(1u << 32 - 1)
340 // If it is outside this range, the sandbox treats the system call just
341 // the same as any other ABI violation (i.e. it aborts with an error
342 // message).
343 static ErrorCode Cond(int argno, ErrorCode::ArgType is_32bit,
344 ErrorCode::Operation op,
345 uint64_t value, const ErrorCode& passed,
346 const ErrorCode& failed);
347
304 // Kill the program and print an error message. 348 // Kill the program and print an error message.
305 static ErrorCode Kill(const char *msg); 349 static ErrorCode Kill(const char *msg);
306 350
307 // This is the main public entry point. It finds all system calls that 351 // This is the main public entry point. It finds all system calls that
308 // need rewriting, sets up the resources needed by the sandbox, and 352 // need rewriting, sets up the resources needed by the sandbox, and
309 // enters Seccomp mode. 353 // enters Seccomp mode.
310 static void startSandbox() { startSandboxInternal(false); } 354 static void StartSandbox() { StartSandboxInternal(false); }
311 355
312 private: 356 private:
313 friend class ErrorCode;
314 friend class CodeGen; 357 friend class CodeGen;
315 friend class SandboxUnittestHelper; 358 friend class SandboxUnittestHelper;
359 friend class ErrorCode;
316 friend class Util; 360 friend class Util;
317 friend class Verifier; 361 friend class Verifier;
318 362
319 typedef std::vector<struct sock_filter> Program; 363 typedef std::vector<struct sock_filter> Program;
320 364
321 struct Range { 365 struct Range {
322 Range(uint32_t f, uint32_t t, const ErrorCode& e) 366 Range(uint32_t f, uint32_t t, const ErrorCode& e)
323 : from(f), 367 : from(f),
324 to(t), 368 to(t),
325 err(e) { 369 err(e) {
326 } 370 }
327 uint32_t from, to; 371 uint32_t from, to;
328 ErrorCode err; 372 ErrorCode err;
329 }; 373 };
330 struct TrapKey { 374 struct TrapKey {
331 TrapKey(TrapFnc f, const void *a, bool s) 375 TrapKey(TrapFnc f, const void *a, bool s)
332 : fnc(f), 376 : fnc(f),
333 aux(a), 377 aux(a),
334 safe(s) { 378 safe(s) {
335 } 379 }
336 TrapFnc fnc; 380 TrapFnc fnc;
337 const void *aux; 381 const void *aux;
338 bool safe; 382 bool safe;
339 bool operator<(const TrapKey&) const; 383 bool operator<(const TrapKey&) const;
340 }; 384 };
341 typedef std::vector<Range> Ranges; 385 typedef std::vector<Range> Ranges;
342 typedef std::map<uint32_t, ErrorCode> ErrMap; 386 typedef std::map<uint32_t, ErrorCode> ErrMap;
343 typedef std::vector<ErrorCode> Traps; 387 typedef std::vector<ErrorCode> Traps;
344 typedef std::map<TrapKey, uint16_t> TrapIds; 388 typedef std::map<TrapKey, uint16_t> TrapIds;
389 typedef std::set<ErrorCode, struct ErrorCode::LessThan> Conds;
345 390
346 // Get a file descriptor pointing to "/proc", if currently available. 391 // Get a file descriptor pointing to "/proc", if currently available.
347 static int proc_fd() { return proc_fd_; } 392 static int ProcFd() { return proc_fd_; }
jln (very slow on Chromium) 2012/12/14 02:28:02 Nit: for accessors, the correct is indeed proc_fd(
348 393
349 static ErrorCode probeEvaluator(int sysnum, void *) __attribute__((const)); 394 static ErrorCode ProbeEvaluator(int sysnum, void *) __attribute__((const));
350 static void probeProcess(void); 395 static void ProbeProcess(void);
351 static ErrorCode allowAllEvaluator(int sysnum, void *aux); 396 static ErrorCode AllowAllEvaluator(int sysnum, void *aux);
352 static void tryVsyscallProcess(void); 397 static void TryVsyscallProcess(void);
353 static bool kernelSupportSeccompBPF(int proc_fd); 398 static bool KernelSupportSeccompBPF(int proc_fd);
354 static bool RunFunctionInPolicy(void (*function)(), 399 static bool RunFunctionInPolicy(void (*function)(),
355 EvaluateSyscall syscallEvaluator, 400 EvaluateSyscall syscall_evaluator,
356 void *aux, 401 void *aux,
357 int proc_fd); 402 int proc_fd);
358 static void startSandboxInternal(bool quiet); 403 static void StartSandboxInternal(bool quiet);
359 static bool isSingleThreaded(int proc_fd); 404 static bool IsSingleThreaded(int proc_fd);
360 static bool isDenied(const ErrorCode& code); 405 static bool IsDenied(const ErrorCode& code);
361 static bool disableFilesystem(); 406 static bool DisableFilesystem();
362 static void policySanityChecks(EvaluateSyscall syscallEvaluator, 407 static void PolicySanityChecks(EvaluateSyscall syscall_evaluator,
363 void *aux); 408 void *aux);
364 409
365 // Function that can be passed as a callback function to CodeGen::Traverse(). 410 // Function that can be passed as a callback function to CodeGen::Traverse().
366 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it 411 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
367 // sets the "bool" variable pointed to by "aux". 412 // sets the "bool" variable pointed to by "aux".
368 static void CheckForUnsafeErrorCodes(Instruction *insn, void *aux); 413 static void CheckForUnsafeErrorCodes(Instruction *insn, void *aux);
369 414
370 // Function that can be passed as a callback function to CodeGen::Traverse(). 415 // Function that can be passed as a callback function to CodeGen::Traverse().
371 // Checks whether the "insn" returns an errno value from a BPF filter. If so, 416 // Checks whether the "insn" returns an errno value from a BPF filter. If so,
372 // it rewrites the instruction to instead call a Trap() handler that does 417 // it rewrites the instruction to instead call a Trap() handler that does
373 // the same thing. "aux" is ignored. 418 // the same thing. "aux" is ignored.
374 static void RedirectToUserspace(Instruction *insn, void *aux); 419 static void RedirectToUserspace(Instruction *insn, void *aux);
375 420
376 // Stackable wrapper around an Evaluators handler. Changes ErrorCodes 421 // Stackable wrapper around an Evaluators handler. Changes ErrorCodes
377 // returned by a system call evaluator to match the changes made by 422 // returned by a system call evaluator to match the changes made by
378 // RedirectToUserspace(). "aux" should be pointer to wrapped system call 423 // RedirectToUserspace(). "aux" should be pointer to wrapped system call
379 // evaluator. 424 // evaluator.
380 static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux); 425 static ErrorCode RedirectToUserspaceEvalWrapper(int sysnum, void *aux);
381 426
382 static void installFilter(bool quiet); 427 static void InstallFilter(bool quiet);
383 static void findRanges(Ranges *ranges); 428 static void FindRanges(Ranges *ranges);
384 static Instruction *assembleJumpTable(CodeGen *gen, 429 static Instruction *AssembleJumpTable(CodeGen *gen,
385 Ranges::const_iterator start, 430 Ranges::const_iterator start,
386 Ranges::const_iterator stop); 431 Ranges::const_iterator stop);
387 static void sigSys(int nr, siginfo_t *info, void *void_context); 432 static Instruction *RetExpression(CodeGen *gen, const ErrorCode& cond);
433 static Instruction *CondExpression(CodeGen *gen, const ErrorCode& cond);
434
435 // Returns the fatal ErrorCode that is used to indicate that somebody
436 // attempted to pass a 64bit value in a 32bit system call argument.
437 static ErrorCode Unexpected64bitArgument();
438
439 static void SigSys(int nr, siginfo_t *info, void *void_context);
388 static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe); 440 static ErrorCode MakeTrap(ErrorCode::TrapFnc fn, const void *aux, bool safe);
389 441
390 // A Trap() handler that returns an "errno" value. The value is encoded 442 // A Trap() handler that returns an "errno" value. The value is encoded
391 // in the "aux" parameter. 443 // in the "aux" parameter.
392 static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux); 444 static intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux);
393 445
394 static intptr_t bpfFailure(const struct arch_seccomp_data& data, void *aux); 446 static intptr_t BpfFailure(const struct arch_seccomp_data& data, void *aux);
395 static int getTrapId(TrapFnc fnc, const void *aux);
396 447
397 static SandboxStatus status_; 448 static SandboxStatus status_;
398 static int proc_fd_; 449 static int proc_fd_;
399 static Evaluators evaluators_; 450 static Evaluators evaluators_;
400 static Traps *traps_; 451 static Traps *traps_;
401 static TrapIds trapIds_; 452 static TrapIds trap_ids_;
402 static ErrorCode *trapArray_; 453 static ErrorCode *trap_array_;
403 static size_t trapArraySize_; 454 static size_t trap_array_size_;
404 static bool has_unsafe_traps_; 455 static bool has_unsafe_traps_;
456 static Conds conds_;
457
405 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); 458 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox);
406 }; 459 };
407 460
408 } // namespace 461 } // namespace
409 462
410 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ 463 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698