OLD | NEW |
---|---|
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 #ifndef SYS_SECCOMP | 80 #ifndef SYS_SECCOMP |
81 #define SYS_SECCOMP 1 | 81 #define SYS_SECCOMP 1 |
82 #endif | 82 #endif |
83 | 83 |
84 // Impose some reasonable maximum BPF program size. Realistically, the | 84 // Impose some reasonable maximum BPF program size. Realistically, the |
85 // kernel probably has much lower limits. But by limiting to less than | 85 // kernel probably has much lower limits. But by limiting to less than |
86 // 30 bits, we can ease requirements on some of our data types. | 86 // 30 bits, we can ease requirements on some of our data types. |
87 #define SECCOMP_MAX_PROGRAM_SIZE (1<<30) | 87 #define SECCOMP_MAX_PROGRAM_SIZE (1<<30) |
88 | 88 |
89 #if defined(__i386__) | 89 #if defined(__i386__) |
90 #define MIN_SYSCALL 0u | 90 #define MIN_SYSCALL 0u |
91 #define MAX_SYSCALL 1024u | 91 #define MAX_PUBLIC_SYSCALL 1024u |
92 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL | |
92 #define SECCOMP_ARCH AUDIT_ARCH_I386 | 93 #define SECCOMP_ARCH AUDIT_ARCH_I386 |
93 | 94 |
94 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) | 95 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) |
95 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) | 96 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) |
96 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) | 97 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) |
97 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) | 98 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) |
98 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) | 99 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) |
99 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) | 100 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) |
100 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) | 101 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) |
101 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) | 102 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) |
102 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) | 103 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) |
103 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) | 104 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) |
104 | 105 |
105 #elif defined(__x86_64__) | 106 #elif defined(__x86_64__) |
106 #define MIN_SYSCALL 0u | 107 #define MIN_SYSCALL 0u |
107 #define MAX_SYSCALL 1024u | 108 #define MAX_PUBLIC_SYSCALL 1024u |
109 #define MAX_SYSCALL MAX_PUBLIC_SYSCALL | |
108 #define SECCOMP_ARCH AUDIT_ARCH_X86_64 | 110 #define SECCOMP_ARCH AUDIT_ARCH_X86_64 |
109 | 111 |
110 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) | 112 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) |
111 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) | 113 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) |
112 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) | 114 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) |
113 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) | 115 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) |
114 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) | 116 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) |
115 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) | 117 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) |
116 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) | 118 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) |
117 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) | 119 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) |
118 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) | 120 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) |
119 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) | 121 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) |
120 | 122 |
121 #elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) | 123 #elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) |
122 // ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, | 124 // ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, |
123 // and a "ghost syscall private to the kernel", cmpxchg, | 125 // and a "ghost syscall private to the kernel", cmpxchg, |
124 // at |__ARM_NR_BASE+0x00fff0|. | 126 // at |__ARM_NR_BASE+0x00fff0|. |
125 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. | 127 // See </arch/arm/include/asm/unistd.h> in the Linux kernel. |
126 #define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE) | 128 #define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE) |
127 #define MAX_SYSCALL ((unsigned int)__ARM_NR_BASE + 0x00ffffu) | 129 #define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u) |
130 #define MIN_PRIVATE_SYSCALL ((unsigned int)__ARM_NR_BASE) | |
131 #define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u) | |
132 #define MIN_GHOST_SYSCALL (MIN_PRIVATE_SYSCALL + 0xfff0u) | |
133 #define MAX_SYSCALL (MIN_GHOST_SYSCALL + 8u) | |
128 // <linux/audit.h> includes <linux/elf-em.h>, which does not define EM_ARM. | 134 // <linux/audit.h> includes <linux/elf-em.h>, which does not define EM_ARM. |
129 // <linux/elf.h> only includes <asm/elf.h> if we're in the kernel. | 135 // <linux/elf.h> only includes <asm/elf.h> if we're in the kernel. |
130 # if !defined(EM_ARM) | 136 # if !defined(EM_ARM) |
131 # define EM_ARM 40 | 137 # define EM_ARM 40 |
132 # endif | 138 # endif |
133 #define SECCOMP_ARCH AUDIT_ARCH_ARM | 139 #define SECCOMP_ARCH AUDIT_ARCH_ARM |
134 | 140 |
135 // ARM sigcontext_t is different from i386/x86_64. | 141 // ARM sigcontext_t is different from i386/x86_64. |
136 // See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. | 142 // See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. |
137 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) | 143 #define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) |
138 // ARM EABI syscall convention. | 144 // ARM EABI syscall convention. |
139 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) | 145 #define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) |
140 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) | 146 #define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) |
141 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) | 147 #define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) |
142 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) | 148 #define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) |
143 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) | 149 #define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) |
144 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) | 150 #define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) |
145 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) | 151 #define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) |
146 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) | 152 #define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) |
147 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) | 153 #define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) |
148 | 154 |
149 #else | 155 #else |
150 #error Unsupported target platform | 156 #error Unsupported target platform |
151 | 157 |
152 #endif | 158 #endif |
153 | 159 |
160 #if defined(SECCOMP_BPF_STANDALONE) | |
161 #define arraysize(x) sizeof(x)/sizeof(*(x))) | |
162 #define HANDLE_EINTR TEMP_FAILURE_RETRY | |
163 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ | |
164 TypeName(); \ | |
165 TypeName(const TypeName&); \ | |
166 void operator=(const TypeName&) | |
167 #endif | |
168 | |
154 #include "sandbox/linux/seccomp-bpf/die.h" | 169 #include "sandbox/linux/seccomp-bpf/die.h" |
155 #include "sandbox/linux/seccomp-bpf/errorcode.h" | 170 #include "sandbox/linux/seccomp-bpf/errorcode.h" |
156 | 171 |
157 namespace playground2 { | 172 namespace playground2 { |
158 | 173 |
159 struct arch_seccomp_data { | 174 struct arch_seccomp_data { |
160 int nr; | 175 int nr; |
161 uint32_t arch; | 176 uint32_t arch; |
162 uint64_t instruction_pointer; | 177 uint64_t instruction_pointer; |
163 uint64_t args[6]; | 178 uint64_t args[6]; |
164 }; | 179 }; |
165 | 180 |
166 struct arch_sigsys { | 181 struct arch_sigsys { |
167 void *ip; | 182 void *ip; |
168 int nr; | 183 int nr; |
169 unsigned int arch; | 184 unsigned int arch; |
170 }; | 185 }; |
171 | 186 |
172 #if defined(SECCOMP_BPF_STANDALONE) | |
173 #define arraysize(x) sizeof(x)/sizeof(*(x))) | |
174 #define HANDLE_EINTR TEMP_FAILURE_RETRY | |
175 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ | |
176 TypeName(); \ | |
177 TypeName(const TypeName&); \ | |
178 void operator=(const TypeName&) | |
179 #endif | |
180 | |
181 class Sandbox { | 187 class Sandbox { |
182 public: | 188 public: |
183 enum SandboxStatus { | 189 enum SandboxStatus { |
184 STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox() | 190 STATUS_UNKNOWN, // Status prior to calling supportsSeccompSandbox() |
185 STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing | 191 STATUS_UNSUPPORTED, // The kernel does not appear to support sandboxing |
186 STATUS_UNAVAILABLE, // Currently unavailable but might work again later | 192 STATUS_UNAVAILABLE, // Currently unavailable but might work again later |
187 STATUS_AVAILABLE, // Sandboxing is available but not currently active | 193 STATUS_AVAILABLE, // Sandboxing is available but not currently active |
188 STATUS_ENABLED // The sandbox is now active | 194 STATUS_ENABLED // The sandbox is now active |
189 }; | 195 }; |
190 | 196 |
(...skipping 19 matching lines...) Expand all Loading... | |
210 uint32_t value; | 216 uint32_t value; |
211 ErrorCode passed; | 217 ErrorCode passed; |
212 ErrorCode failed; | 218 ErrorCode failed; |
213 }; | 219 }; |
214 | 220 |
215 typedef ErrorCode (*EvaluateSyscall)(int sysno); | 221 typedef ErrorCode (*EvaluateSyscall)(int sysno); |
216 typedef int (*EvaluateArguments)(int sysno, int arg, | 222 typedef int (*EvaluateArguments)(int sysno, int arg, |
217 Constraint *constraint); | 223 Constraint *constraint); |
218 typedef std::vector<std::pair<EvaluateSyscall,EvaluateArguments> >Evaluators; | 224 typedef std::vector<std::pair<EvaluateSyscall,EvaluateArguments> >Evaluators; |
219 | 225 |
226 // ARM has a non-contiguous range of "private" system calls. | |
227 // Checks whether a particular system call number falls in that range. | |
228 static bool isArmPrivateSyscall(int sysnum); | |
jln (very slow on Chromium)
2012/10/11 22:42:00
This is not a good interface for the Sandbox class
Jorge Lucangeli Obes
2012/10/12 17:58:23
Done.
| |
229 | |
220 // There are a lot of reasons why the Seccomp sandbox might not be available. | 230 // There are a lot of reasons why the Seccomp sandbox might not be available. |
221 // This could be because the kernel does not support Seccomp mode, or it | 231 // This could be because the kernel does not support Seccomp mode, or it |
222 // could be because another sandbox is already active. | 232 // could be because another sandbox is already active. |
223 // "proc_fd" should be a file descriptor for "/proc", or -1 if not | 233 // "proc_fd" should be a file descriptor for "/proc", or -1 if not |
224 // provided by the caller. | 234 // provided by the caller. |
225 static SandboxStatus supportsSeccompSandbox(int proc_fd); | 235 static SandboxStatus supportsSeccompSandbox(int proc_fd); |
226 | 236 |
227 // The sandbox needs to be able to access files in "/proc/self". If this | 237 // The sandbox needs to be able to access files in "/proc/self". If this |
228 // directory is not accessible when "startSandbox()" gets called, the caller | 238 // directory is not accessible when "startSandbox()" gets called, the caller |
229 // can provide an already opened file descriptor by calling "setProcFd()". | 239 // can provide an already opened file descriptor by calling "setProcFd()". |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 typedef std::vector<struct sock_filter> Program; | 294 typedef std::vector<struct sock_filter> Program; |
285 typedef std::map<uint32_t, ErrorCode> ErrMap; | 295 typedef std::map<uint32_t, ErrorCode> ErrMap; |
286 typedef std::vector<ErrorCode> Traps; | 296 typedef std::vector<ErrorCode> Traps; |
287 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; | 297 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; |
288 | 298 |
289 // Get a file descriptor pointing to "/proc", if currently available. | 299 // Get a file descriptor pointing to "/proc", if currently available. |
290 static int proc_fd() { return proc_fd_; } | 300 static int proc_fd() { return proc_fd_; } |
291 | 301 |
292 static ErrorCode probeEvaluator(int signo) __attribute__((const)); | 302 static ErrorCode probeEvaluator(int signo) __attribute__((const)); |
293 static void probeProcess(void); | 303 static void probeProcess(void); |
294 static ErrorCode allowAllEvaluator(int signo); | 304 static ErrorCode allowAllEvaluator(int sysnum); |
295 static void tryVsyscallProcess(void); | 305 static void tryVsyscallProcess(void); |
296 static bool kernelSupportSeccompBPF(int proc_fd); | 306 static bool kernelSupportSeccompBPF(int proc_fd); |
297 static bool RunFunctionInPolicy(void (*function)(), | 307 static bool RunFunctionInPolicy(void (*function)(), |
298 EvaluateSyscall syscallEvaluator, | 308 EvaluateSyscall syscallEvaluator, |
299 int proc_fd); | 309 int proc_fd); |
300 static void startSandboxInternal(bool quiet); | 310 static void startSandboxInternal(bool quiet); |
301 static bool isSingleThreaded(int proc_fd); | 311 static bool isSingleThreaded(int proc_fd); |
302 static bool isDenied(const ErrorCode& code); | 312 static bool isDenied(const ErrorCode& code); |
303 static bool disableFilesystem(); | 313 static bool disableFilesystem(); |
304 static void policySanityChecks(EvaluateSyscall syscallEvaluator, | 314 static void policySanityChecks(EvaluateSyscall syscallEvaluator, |
(...skipping 15 matching lines...) Expand all Loading... | |
320 static Traps *traps_; | 330 static Traps *traps_; |
321 static TrapIds trapIds_; | 331 static TrapIds trapIds_; |
322 static ErrorCode *trapArray_; | 332 static ErrorCode *trapArray_; |
323 static size_t trapArraySize_; | 333 static size_t trapArraySize_; |
324 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); | 334 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); |
325 }; | 335 }; |
326 | 336 |
327 } // namespace | 337 } // namespace |
328 | 338 |
329 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ | 339 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ |
OLD | NEW |