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 #include "content/public/common/sandbox_init.h" | 5 #include "content/public/common/sandbox_init.h" |
6 | 6 |
7 #if defined(OS_LINUX) && defined(__x86_64__) | 7 #if defined(OS_LINUX) && defined(__x86_64__) |
8 | 8 |
9 #include <asm/unistd.h> | 9 #include <asm/unistd.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 30 matching lines...) Expand all Loading... | |
41 #endif | 41 #endif |
42 | 42 |
43 #ifndef __NR_readlinkat | 43 #ifndef __NR_readlinkat |
44 #define __NR_readlinkat 267 | 44 #define __NR_readlinkat 267 |
45 #endif | 45 #endif |
46 | 46 |
47 #ifndef __NR_eventfd2 | 47 #ifndef __NR_eventfd2 |
48 #define __NR_eventfd2 290 | 48 #define __NR_eventfd2 290 |
49 #endif | 49 #endif |
50 | 50 |
51 #ifndef __NR_process_vm_readv | |
52 #define __NR_process_vm_readv 310 | |
53 #endif | |
54 | |
55 #ifndef __NR_process_vm_writev | |
56 #define __NR_process_vm_writev 311 | |
57 #endif | |
58 | |
51 // Constants from very new header files that we can't yet include. | 59 // Constants from very new header files that we can't yet include. |
52 #ifndef SECCOMP_MODE_FILTER | 60 #ifndef SECCOMP_MODE_FILTER |
53 #define SECCOMP_MODE_FILTER 2 | 61 #define SECCOMP_MODE_FILTER 2 |
54 #define SECCOMP_RET_KILL 0x00000000U | 62 #define SECCOMP_RET_KILL 0x00000000U |
55 #define SECCOMP_RET_TRAP 0x00030000U | 63 #define SECCOMP_RET_TRAP 0x00030000U |
56 #define SECCOMP_RET_ERRNO 0x00050000U | 64 #define SECCOMP_RET_ERRNO 0x00050000U |
57 #define SECCOMP_RET_ALLOW 0x7fff0000U | 65 #define SECCOMP_RET_ALLOW 0x7fff0000U |
58 #endif | 66 #endif |
59 | 67 |
60 | 68 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 // "4" is magic offset for the arch number. | 166 // "4" is magic offset for the arch number. |
159 EmitLoad(4, program); | 167 EmitLoad(4, program); |
160 EmitJEQJT1(AUDIT_ARCH_X86_64, program); | 168 EmitJEQJT1(AUDIT_ARCH_X86_64, program); |
161 EmitRet(SECCOMP_RET_KILL, program); | 169 EmitRet(SECCOMP_RET_KILL, program); |
162 | 170 |
163 // Load the syscall number. | 171 // Load the syscall number. |
164 // "0" is magic offset for the syscall number. | 172 // "0" is magic offset for the syscall number. |
165 EmitLoad(0, program); | 173 EmitLoad(0, program); |
166 } | 174 } |
167 | 175 |
176 static void EmitTrap(std::vector<struct sock_filter>* program) { | |
177 EmitRet(SECCOMP_RET_TRAP, program); | |
178 } | |
179 | |
180 static void EmitAllow(std::vector<struct sock_filter>* program) { | |
181 EmitRet(SECCOMP_RET_ALLOW, program); | |
182 } | |
183 | |
168 static void EmitAllowSyscall(int nr, std::vector<struct sock_filter>* program) { | 184 static void EmitAllowSyscall(int nr, std::vector<struct sock_filter>* program) { |
169 EmitJEQJF(nr, 1, program); | 185 EmitJEQJF(nr, 1, program); |
170 EmitRet(SECCOMP_RET_ALLOW, program); | 186 EmitAllow(program); |
187 } | |
188 | |
189 static void EmitDenySyscall(int nr, std::vector<struct sock_filter>* program) { | |
190 EmitJEQJF(nr, 1, program); | |
191 EmitTrap(program); | |
171 } | 192 } |
172 | 193 |
173 static void EmitAllowSyscallArgN(int nr, | 194 static void EmitAllowSyscallArgN(int nr, |
174 int arg_nr, | 195 int arg_nr, |
175 int arg_val, | 196 int arg_val, |
176 std::vector<struct sock_filter>* program) { | 197 std::vector<struct sock_filter>* program) { |
177 // Jump forward 4 on no-match so that we also skip the unneccessary reload of | 198 // Jump forward 4 on no-match so that we also skip the unneccessary reload of |
178 // syscall_nr. (It is unneccessary because we have not trashed it yet.) | 199 // syscall_nr. (It is unneccessary because we have not trashed it yet.) |
179 EmitJEQJF(nr, 4, program); | 200 EmitJEQJF(nr, 4, program); |
180 EmitLoadArg(arg_nr, program); | 201 EmitLoadArg(arg_nr, program); |
181 EmitJEQJF(arg_val, 1, program); | 202 EmitJEQJF(arg_val, 1, program); |
182 EmitRet(SECCOMP_RET_ALLOW, program); | 203 EmitAllow(program); |
183 // We trashed syscall_nr so put it back in the accumulator. | 204 // We trashed syscall_nr so put it back in the accumulator. |
184 EmitLoad(0, program); | 205 EmitLoad(0, program); |
185 } | 206 } |
186 | 207 |
187 static void EmitFailSyscall(int nr, int err, | 208 static void EmitFailSyscall(int nr, int err, |
188 std::vector<struct sock_filter>* program) { | 209 std::vector<struct sock_filter>* program) { |
189 EmitJEQJF(nr, 1, program); | 210 EmitJEQJF(nr, 1, program); |
190 EmitRet(SECCOMP_RET_ERRNO | err, program); | 211 EmitRet(SECCOMP_RET_ERRNO | err, program); |
191 } | 212 } |
192 | 213 |
193 static void EmitTrap(std::vector<struct sock_filter>* program) { | |
194 EmitRet(SECCOMP_RET_TRAP, program); | |
195 } | |
196 | |
197 // TODO(cevans) -- only really works as advertised once we restrict clone() | 214 // TODO(cevans) -- only really works as advertised once we restrict clone() |
198 // to CLONE_THREAD. | 215 // to CLONE_THREAD. |
199 static void EmitAllowSignalSelf(std::vector<struct sock_filter>* program) { | 216 static void EmitAllowSignalSelf(std::vector<struct sock_filter>* program) { |
200 EmitAllowSyscallArgN(__NR_kill, 1, getpid(), program); | 217 EmitAllowSyscallArgN(__NR_kill, 1, getpid(), program); |
201 EmitAllowSyscallArgN(__NR_tgkill, 1, getpid(), program); | 218 EmitAllowSyscallArgN(__NR_tgkill, 1, getpid(), program); |
202 } | 219 } |
203 | 220 |
204 static void EmitAllowGettime(std::vector<struct sock_filter>* program) { | 221 static void EmitAllowGettime(std::vector<struct sock_filter>* program) { |
205 EmitAllowSyscall(__NR_clock_gettime, program); | 222 EmitAllowSyscall(__NR_clock_gettime, program); |
206 EmitAllowSyscall(__NR_gettimeofday, program); | 223 EmitAllowSyscall(__NR_gettimeofday, program); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 EmitAllowSignalSelf(program); | 343 EmitAllowSignalSelf(program); |
327 | 344 |
328 // These are under investigation, and hopefully not here for the long term. | 345 // These are under investigation, and hopefully not here for the long term. |
329 EmitAllowSyscall(__NR_shmctl, program); | 346 EmitAllowSyscall(__NR_shmctl, program); |
330 EmitAllowSyscall(__NR_shmat, program); | 347 EmitAllowSyscall(__NR_shmat, program); |
331 EmitAllowSyscall(__NR_shmdt, program); | 348 EmitAllowSyscall(__NR_shmdt, program); |
332 | 349 |
333 EmitSetupEmptyFileSystem(program); | 350 EmitSetupEmptyFileSystem(program); |
334 } | 351 } |
335 | 352 |
353 static void ApplyNoPtracePolicy(std::vector<struct sock_filter>* program) { | |
354 EmitDenySyscall(__NR_ptrace, program); | |
355 EmitDenySyscall(__NR_process_vm_readv, program); | |
356 EmitDenySyscall(__NR_process_vm_writev, program); | |
jln (very slow on Chromium)
2012/06/01 18:34:37
Not a huge deal, but maybe add move_pages and migr
| |
357 } | |
358 | |
336 static bool CanUseSeccompFilters() { | 359 static bool CanUseSeccompFilters() { |
337 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); | 360 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); |
338 if (ret != 0 && errno == EFAULT) | 361 if (ret != 0 && errno == EFAULT) |
339 return true; | 362 return true; |
340 return false; | 363 return false; |
341 } | 364 } |
342 | 365 |
343 static void InstallFilter(const std::vector<struct sock_filter>& program) { | 366 static void InstallFilter(const std::vector<struct sock_filter>& program) { |
344 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 367 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
345 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; | 368 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; |
(...skipping 27 matching lines...) Expand all Loading... | |
373 | 396 |
374 CheckSingleThreaded(); | 397 CheckSingleThreaded(); |
375 | 398 |
376 std::vector<struct sock_filter> program; | 399 std::vector<struct sock_filter> program; |
377 EmitPreamble(&program); | 400 EmitPreamble(&program); |
378 | 401 |
379 if (process_type == switches::kGpuProcess) { | 402 if (process_type == switches::kGpuProcess) { |
380 ApplyGPUPolicy(&program); | 403 ApplyGPUPolicy(&program); |
381 } else if (process_type == switches::kPpapiPluginProcess) { | 404 } else if (process_type == switches::kPpapiPluginProcess) { |
382 ApplyFlashPolicy(&program); | 405 ApplyFlashPolicy(&program); |
406 } else if (process_type == switches::kRendererProcess || | |
407 process_type == switches::kWorkerProcess) { | |
408 ApplyNoPtracePolicy(&program); | |
383 } else { | 409 } else { |
jln (very slow on Chromium)
2012/06/01 18:34:37
This whole section (up to line 418) is becoming di
| |
384 NOTREACHED(); | 410 NOTREACHED(); |
385 } | 411 } |
386 | 412 |
387 EmitTrap(&program); | 413 if (process_type == switches::kRendererProcess || |
414 process_type == switches::kWorkerProcess) { | |
415 EmitAllow(&program); | |
416 } else { | |
417 EmitTrap(&program); | |
418 } | |
388 | 419 |
389 InstallSIGSYSHandler(); | 420 InstallSIGSYSHandler(); |
390 InstallFilter(program); | 421 InstallFilter(program); |
391 } | 422 } |
392 | 423 |
393 } // namespace content | 424 } // namespace content |
394 | 425 |
395 #else | 426 #else |
396 | 427 |
397 namespace content { | 428 namespace content { |
398 | 429 |
399 void InitializeSandbox() { | 430 void InitializeSandbox() { |
400 } | 431 } |
401 | 432 |
402 } // namespace content | 433 } // namespace content |
403 | 434 |
404 #endif | 435 #endif |
405 | 436 |
OLD | NEW |