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. 4 5#ifndef SANDBOX_LINUX_SECCOMP_BPF_LINUX_SECCOMP_H__ 6#define SANDBOX_LINUX_SECCOMP_BPF_LINUX_SECCOMP_H__ 7 8// The Seccomp2 kernel ABI is not part of older versions of glibc. 9// As we can't break compilation with these versions of the library, 10// we explicitly define all missing symbols. 11// If we ever decide that we can now rely on system headers, the following 12// include files should be enabled: 13// #include <linux/audit.h> 14// #include <linux/seccomp.h> 15 16#include <asm/unistd.h> 17#include <linux/filter.h> 18 19#include <sys/cdefs.h> 20// Old Bionic versions do not have sys/user.h. The if can be removed once we no 21// longer need to support these old Bionic versions. 22// All x86_64 builds use a new enough bionic to have sys/user.h. 23#if !defined(__BIONIC__) || defined(__x86_64__) 24#include <sys/types.h> // Fix for gcc 4.7, make sure __uint16_t is defined. 25#include <sys/user.h> 26#if defined(__mips__) 27// sys/user.h in eglibc misses size_t definition 28#include <stddef.h> 29#endif 30#endif 31 32// For audit.h 33#ifndef EM_ARM 34#define EM_ARM 40 35#endif 36#ifndef EM_386 37#define EM_386 3 38#endif 39#ifndef EM_X86_64 40#define EM_X86_64 62 41#endif 42#ifndef EM_MIPS 43#define EM_MIPS 8 44#endif 45#ifndef EM_AARCH64 46#define EM_AARCH64 183 47#endif 48 49#ifndef __AUDIT_ARCH_64BIT 50#define __AUDIT_ARCH_64BIT 0x80000000 51#endif 52#ifndef __AUDIT_ARCH_LE 53#define __AUDIT_ARCH_LE 0x40000000 54#endif 55#ifndef AUDIT_ARCH_ARM 56#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE) 57#endif 58#ifndef AUDIT_ARCH_I386 59#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE) 60#endif 61#ifndef AUDIT_ARCH_X86_64 62#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE) 63#endif 64#ifndef AUDIT_ARCH_MIPSEL 65#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE) 66#endif 67#ifndef AUDIT_ARCH_AARCH64 68#define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE) 69#endif 70 71// For prctl.h 72#ifndef PR_SET_SECCOMP 73#define PR_SET_SECCOMP 22 74#define PR_GET_SECCOMP 21 75#endif 76#ifndef PR_SET_NO_NEW_PRIVS 77#define PR_SET_NO_NEW_PRIVS 38 78#define PR_GET_NO_NEW_PRIVS 39 79#endif 80#ifndef IPC_64 81#define IPC_64 0x0100 82#endif 83 84#ifndef BPF_MOD 85#define BPF_MOD 0x90 86#endif 87#ifndef BPF_XOR 88#define BPF_XOR 0xA0 89#endif 90 91// In order to build will older tool chains, we currently have to avoid 92// including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on 93// our own definitions of the seccomp kernel ABI. 94#ifndef SECCOMP_MODE_FILTER 95#define SECCOMP_MODE_DISABLED 0 96#define SECCOMP_MODE_STRICT 1 97#define SECCOMP_MODE_FILTER 2 // User user-supplied filter 98#endif 99 100#ifndef SECCOMP_SET_MODE_STRICT 101#define SECCOMP_SET_MODE_STRICT 0 102#endif 103#ifndef SECCOMP_SET_MODE_FILTER 104#define SECCOMP_SET_MODE_FILTER 1 105#endif 106#ifndef SECCOMP_FILTER_FLAG_TSYNC 107#define SECCOMP_FILTER_FLAG_TSYNC 1 108#endif 109 110#ifndef SECCOMP_RET_KILL 111// Return values supported for BPF filter programs. Please note that the 112// "illegal" SECCOMP_RET_INVALID is not supported by the kernel, should only 113// ever be used internally, and would result in the kernel killing our process. 114#define SECCOMP_RET_KILL 0x00000000U // Kill the task immediately 115#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value 116#define SECCOMP_RET_TRAP 0x00030000U // Disallow and force a SIGSYS 117#define SECCOMP_RET_ERRNO 0x00050000U // Returns an errno 118#define SECCOMP_RET_TRACE 0x7ff00000U // Pass to a tracer or disallow 119#define SECCOMP_RET_ALLOW 0x7fff0000U // Allow 120#define SECCOMP_RET_ACTION 0xffff0000U // Masks for the return value 121#define SECCOMP_RET_DATA 0x0000ffffU // sections 122#else 123#define SECCOMP_RET_INVALID 0x00010000U // Illegal return value 124#endif 125 126#ifndef SYS_SECCOMP 127#define SYS_SECCOMP 1 128#endif 129 130// Impose some reasonable maximum BPF program size. Realistically, the 131// kernel probably has much lower limits. But by limiting to less than 132// 30 bits, we can ease requirements on some of our data types. 133#define SECCOMP_MAX_PROGRAM_SIZE (1<<30) 134 135#if defined(__i386__) 136#define MIN_SYSCALL 0u 137#define MAX_PUBLIC_SYSCALL 1024u 138#define MAX_SYSCALL MAX_PUBLIC_SYSCALL 139#define SECCOMP_ARCH AUDIT_ARCH_I386 140 141#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 142#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) 143#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) 144#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) 145#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) 146#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) 147#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) 148#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) 149#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) 150#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) 151#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 152#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 153#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 154 instruction_pointer) + 4) 155#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 156 instruction_pointer) + 0) 157#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 158 8*(nr) + 4) 159#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 160 8*(nr) + 0) 161 162 163#if defined(__BIONIC__) 164// Old Bionic versions don't have sys/user.h, so we just define regs_struct 165// directly. This can be removed once we no longer need to support these old 166// Bionic versions. 167struct regs_struct { 168 long int ebx; 169 long int ecx; 170 long int edx; 171 long int esi; 172 long int edi; 173 long int ebp; 174 long int eax; 175 long int xds; 176 long int xes; 177 long int xfs; 178 long int xgs; 179 long int orig_eax; 180 long int eip; 181 long int xcs; 182 long int eflags; 183 long int esp; 184 long int xss; 185}; 186#else 187typedef user_regs_struct regs_struct; 188#endif 189 190#define SECCOMP_PT_RESULT(_regs) (_regs).eax 191#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_eax 192#define SECCOMP_PT_IP(_regs) (_regs).eip 193#define SECCOMP_PT_PARM1(_regs) (_regs).ebx 194#define SECCOMP_PT_PARM2(_regs) (_regs).ecx 195#define SECCOMP_PT_PARM3(_regs) (_regs).edx 196#define SECCOMP_PT_PARM4(_regs) (_regs).esi 197#define SECCOMP_PT_PARM5(_regs) (_regs).edi 198#define SECCOMP_PT_PARM6(_regs) (_regs).ebp 199 200#elif defined(__x86_64__) 201#define MIN_SYSCALL 0u 202#define MAX_PUBLIC_SYSCALL 1024u 203#define MAX_SYSCALL MAX_PUBLIC_SYSCALL 204#define SECCOMP_ARCH AUDIT_ARCH_X86_64 205 206#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 207#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) 208#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) 209#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) 210#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) 211#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) 212#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) 213#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) 214#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) 215#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) 216#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 217#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 218#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 219 instruction_pointer) + 4) 220#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 221 instruction_pointer) + 0) 222#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 223 8*(nr) + 4) 224#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 225 8*(nr) + 0) 226 227typedef user_regs_struct regs_struct; 228#define SECCOMP_PT_RESULT(_regs) (_regs).rax 229#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_rax 230#define SECCOMP_PT_IP(_regs) (_regs).rip 231#define SECCOMP_PT_PARM1(_regs) (_regs).rdi 232#define SECCOMP_PT_PARM2(_regs) (_regs).rsi 233#define SECCOMP_PT_PARM3(_regs) (_regs).rdx 234#define SECCOMP_PT_PARM4(_regs) (_regs).r10 235#define SECCOMP_PT_PARM5(_regs) (_regs).r8 236#define SECCOMP_PT_PARM6(_regs) (_regs).r9 237 238#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) 239// ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|, 240// and a "ghost syscall private to the kernel", cmpxchg, 241// at |__ARM_NR_BASE+0x00fff0|. 242// See </arch/arm/include/asm/unistd.h> in the Linux kernel. 243#define MIN_SYSCALL ((unsigned int)__NR_SYSCALL_BASE) 244#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + 1024u) 245#define MIN_PRIVATE_SYSCALL ((unsigned int)__ARM_NR_BASE) 246#define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u) 247#define MIN_GHOST_SYSCALL ((unsigned int)__ARM_NR_BASE + 0xfff0u) 248#define MAX_SYSCALL (MIN_GHOST_SYSCALL + 4u) 249 250#define SECCOMP_ARCH AUDIT_ARCH_ARM 251 252// ARM sigcontext_t is different from i386/x86_64. 253// See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. 254#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) 255// ARM EABI syscall convention. 256#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) 257#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) 258#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) 259#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) 260#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) 261#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) 262#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) 263#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) 264#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) 265#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 266#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 267#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 268 instruction_pointer) + 4) 269#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 270 instruction_pointer) + 0) 271#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 272 8*(nr) + 4) 273#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 274 8*(nr) + 0) 275 276#if defined(__BIONIC__) 277// Old Bionic versions don't have sys/user.h, so we just define regs_struct 278// directly. This can be removed once we no longer need to support these old 279// Bionic versions. 280struct regs_struct { 281 unsigned long uregs[18]; 282}; 283#else 284typedef user_regs regs_struct; 285#endif 286 287#define REG_cpsr uregs[16] 288#define REG_pc uregs[15] 289#define REG_lr uregs[14] 290#define REG_sp uregs[13] 291#define REG_ip uregs[12] 292#define REG_fp uregs[11] 293#define REG_r10 uregs[10] 294#define REG_r9 uregs[9] 295#define REG_r8 uregs[8] 296#define REG_r7 uregs[7] 297#define REG_r6 uregs[6] 298#define REG_r5 uregs[5] 299#define REG_r4 uregs[4] 300#define REG_r3 uregs[3] 301#define REG_r2 uregs[2] 302#define REG_r1 uregs[1] 303#define REG_r0 uregs[0] 304#define REG_ORIG_r0 uregs[17] 305 306#define SECCOMP_PT_RESULT(_regs) (_regs).REG_r0 307#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_r7 308#define SECCOMP_PT_IP(_regs) (_regs).REG_pc 309#define SECCOMP_PT_PARM1(_regs) (_regs).REG_r0 310#define SECCOMP_PT_PARM2(_regs) (_regs).REG_r1 311#define SECCOMP_PT_PARM3(_regs) (_regs).REG_r2 312#define SECCOMP_PT_PARM4(_regs) (_regs).REG_r3 313#define SECCOMP_PT_PARM5(_regs) (_regs).REG_r4 314#define SECCOMP_PT_PARM6(_regs) (_regs).REG_r5 315 316#elif defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) 317#define MIN_SYSCALL __NR_O32_Linux 318#define MAX_PUBLIC_SYSCALL (MIN_SYSCALL + __NR_Linux_syscalls) 319#define MAX_SYSCALL MAX_PUBLIC_SYSCALL 320#define SECCOMP_ARCH AUDIT_ARCH_MIPSEL 321#define SYSCALL_EIGHT_ARGS 322// MIPS sigcontext_t is different from i386/x86_64 and ARM. 323// See </arch/mips/include/uapi/asm/sigcontext.h> in the Linux kernel. 324#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[_reg]) 325// Based on MIPS o32 ABI syscall convention. 326// On MIPS, when indirect syscall is being made (syscall(__NR_foo)), 327// real identificator (__NR_foo) is not in v0, but in a0 328#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 2) 329#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 2) 330#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc 331#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 4) 332#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 5) 333#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 6) 334#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 7) 335// Only the first 4 arguments of syscall are in registers. 336// The rest are on the stack. 337#define SECCOMP_STACKPARM(_ctx, n) (((long *)SECCOMP_REG(_ctx, 29))[(n)]) 338#define SECCOMP_PARM5(_ctx) SECCOMP_STACKPARM(_ctx, 4) 339#define SECCOMP_PARM6(_ctx) SECCOMP_STACKPARM(_ctx, 5) 340#define SECCOMP_PARM7(_ctx) SECCOMP_STACKPARM(_ctx, 6) 341#define SECCOMP_PARM8(_ctx) SECCOMP_STACKPARM(_ctx, 7) 342#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 343#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 344#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 345 instruction_pointer) + 4) 346#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 347 instruction_pointer) + 0) 348#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 349 8*(nr) + 4) 350#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 351 8*(nr) + 0) 352 353// On Mips we don't have structures like user_regs or user_regs_struct in 354// sys/user.h that we could use, so we just define regs_struct directly. 355struct regs_struct { 356 unsigned long long regs[32]; 357}; 358 359#define REG_a3 regs[7] 360#define REG_a2 regs[6] 361#define REG_a1 regs[5] 362#define REG_a0 regs[4] 363#define REG_v1 regs[3] 364#define REG_v0 regs[2] 365 366#define SECCOMP_PT_RESULT(_regs) (_regs).REG_v0 367#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_v0 368#define SECCOMP_PT_PARM1(_regs) (_regs).REG_a0 369#define SECCOMP_PT_PARM2(_regs) (_regs).REG_a1 370#define SECCOMP_PT_PARM3(_regs) (_regs).REG_a2 371#define SECCOMP_PT_PARM4(_regs) (_regs).REG_a3 372 373#elif defined(__aarch64__) 374struct regs_struct { 375 unsigned long long regs[31]; 376 unsigned long long sp; 377 unsigned long long pc; 378 unsigned long long pstate; 379}; 380 381#define MIN_SYSCALL 0u 382#define MAX_PUBLIC_SYSCALL 279u 383#define MAX_SYSCALL MAX_PUBLIC_SYSCALL 384#define SECCOMP_ARCH AUDIT_ARCH_AARCH64 385 386#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.regs[_reg]) 387 388#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 0) 389#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 8) 390#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc 391#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 0) 392#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 1) 393#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 2) 394#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 3) 395#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, 4) 396#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, 5) 397 398#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 399#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 400#define SECCOMP_IP_MSB_IDX \ 401 (offsetof(struct arch_seccomp_data, instruction_pointer) + 4) 402#define SECCOMP_IP_LSB_IDX \ 403 (offsetof(struct arch_seccomp_data, instruction_pointer) + 0) 404#define SECCOMP_ARG_MSB_IDX(nr) \ 405 (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 4) 406#define SECCOMP_ARG_LSB_IDX(nr) \ 407 (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 0) 408 409#define SECCOMP_PT_RESULT(_regs) (_regs).regs[0] 410#define SECCOMP_PT_SYSCALL(_regs) (_regs).regs[8] 411#define SECCOMP_PT_IP(_regs) (_regs).pc 412#define SECCOMP_PT_PARM1(_regs) (_regs).regs[0] 413#define SECCOMP_PT_PARM2(_regs) (_regs).regs[1] 414#define SECCOMP_PT_PARM3(_regs) (_regs).regs[2] 415#define SECCOMP_PT_PARM4(_regs) (_regs).regs[3] 416#define SECCOMP_PT_PARM5(_regs) (_regs).regs[4] 417#define SECCOMP_PT_PARM6(_regs) (_regs).regs[5] 418#else 419#error Unsupported target platform 420 421#endif 422 423#endif // SANDBOX_LINUX_SECCOMP_BPF_LINUX_SECCOMP_H__ 424