| 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 ((unsigned int)__ARM_NR_BASE + 0xfff0u) |
| 133 #define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u) |
| 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 // Checks whether a particular system call number is valid on the current |
| 227 // architecture. E.g. on ARM there's a non-contiguous range of private |
| 228 // system calls. |
| 229 static bool isValidSyscallNumber(int sysnum); |
| 230 |
| 220 // There are a lot of reasons why the Seccomp sandbox might not be available. | 231 // 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 | 232 // This could be because the kernel does not support Seccomp mode, or it |
| 222 // could be because another sandbox is already active. | 233 // could be because another sandbox is already active. |
| 223 // "proc_fd" should be a file descriptor for "/proc", or -1 if not | 234 // "proc_fd" should be a file descriptor for "/proc", or -1 if not |
| 224 // provided by the caller. | 235 // provided by the caller. |
| 225 static SandboxStatus supportsSeccompSandbox(int proc_fd); | 236 static SandboxStatus supportsSeccompSandbox(int proc_fd); |
| 226 | 237 |
| 227 // The sandbox needs to be able to access files in "/proc/self". If this | 238 // 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 | 239 // directory is not accessible when "startSandbox()" gets called, the caller |
| 229 // can provide an already opened file descriptor by calling "setProcFd()". | 240 // 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; | 295 typedef std::vector<struct sock_filter> Program; |
| 285 typedef std::map<uint32_t, ErrorCode> ErrMap; | 296 typedef std::map<uint32_t, ErrorCode> ErrMap; |
| 286 typedef std::vector<ErrorCode> Traps; | 297 typedef std::vector<ErrorCode> Traps; |
| 287 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; | 298 typedef std::map<std::pair<TrapFnc, const void *>, int> TrapIds; |
| 288 | 299 |
| 289 // Get a file descriptor pointing to "/proc", if currently available. | 300 // Get a file descriptor pointing to "/proc", if currently available. |
| 290 static int proc_fd() { return proc_fd_; } | 301 static int proc_fd() { return proc_fd_; } |
| 291 | 302 |
| 292 static ErrorCode probeEvaluator(int signo) __attribute__((const)); | 303 static ErrorCode probeEvaluator(int signo) __attribute__((const)); |
| 293 static void probeProcess(void); | 304 static void probeProcess(void); |
| 294 static ErrorCode allowAllEvaluator(int signo); | 305 static ErrorCode allowAllEvaluator(int sysnum); |
| 295 static void tryVsyscallProcess(void); | 306 static void tryVsyscallProcess(void); |
| 296 static bool kernelSupportSeccompBPF(int proc_fd); | 307 static bool kernelSupportSeccompBPF(int proc_fd); |
| 297 static bool RunFunctionInPolicy(void (*function)(), | 308 static bool RunFunctionInPolicy(void (*function)(), |
| 298 EvaluateSyscall syscallEvaluator, | 309 EvaluateSyscall syscallEvaluator, |
| 299 int proc_fd); | 310 int proc_fd); |
| 300 static void startSandboxInternal(bool quiet); | 311 static void startSandboxInternal(bool quiet); |
| 301 static bool isSingleThreaded(int proc_fd); | 312 static bool isSingleThreaded(int proc_fd); |
| 302 static bool isDenied(const ErrorCode& code); | 313 static bool isDenied(const ErrorCode& code); |
| 303 static bool disableFilesystem(); | 314 static bool disableFilesystem(); |
| 304 static void policySanityChecks(EvaluateSyscall syscallEvaluator, | 315 static void policySanityChecks(EvaluateSyscall syscallEvaluator, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 320 static Traps *traps_; | 331 static Traps *traps_; |
| 321 static TrapIds trapIds_; | 332 static TrapIds trapIds_; |
| 322 static ErrorCode *trapArray_; | 333 static ErrorCode *trapArray_; |
| 323 static size_t trapArraySize_; | 334 static size_t trapArraySize_; |
| 324 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); | 335 DISALLOW_IMPLICIT_CONSTRUCTORS(Sandbox); |
| 325 }; | 336 }; |
| 326 | 337 |
| 327 } // namespace | 338 } // namespace |
| 328 | 339 |
| 329 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ | 340 #endif // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_H__ |
| OLD | NEW |