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_BPF_DSL_SECCOMP_MACROS_H_ 6#define SANDBOX_LINUX_BPF_DSL_SECCOMP_MACROS_H_ 7 8#include <sys/types.h> // For __BIONIC__. 9// Old Bionic versions do not have sys/user.h. The if can be removed once we no 10// longer need to support these old Bionic versions. 11// All x86_64 builds use a new enough bionic to have sys/user.h. 12#if !defined(__BIONIC__) || defined(__x86_64__) 13#if !defined(__native_client_nonsfi__) 14#include <sys/user.h> 15#endif 16#if defined(__mips__) 17// sys/user.h in eglibc misses size_t definition 18#include <stddef.h> 19#endif 20#endif 21 22#include "sandbox/linux/system_headers/linux_seccomp.h" // For AUDIT_ARCH_* 23 24// Impose some reasonable maximum BPF program size. Realistically, the 25// kernel probably has much lower limits. But by limiting to less than 26// 30 bits, we can ease requirements on some of our data types. 27#define SECCOMP_MAX_PROGRAM_SIZE (1<<30) 28 29#if defined(__i386__) 30#define SECCOMP_ARCH AUDIT_ARCH_I386 31 32#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 33#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_EAX) 34#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_EAX) 35#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_EIP) 36#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_EBX) 37#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_ECX) 38#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_EDX) 39#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_ESI) 40#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_EDI) 41#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_EBP) 42#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 43#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 44#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 45 instruction_pointer) + 4) 46#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 47 instruction_pointer) + 0) 48#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 49 8*(nr) + 4) 50#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 51 8*(nr) + 0) 52 53 54#if defined(__BIONIC__) || defined(__native_client_nonsfi__) 55// Old Bionic versions and PNaCl toolchain don't have sys/user.h, so we just 56// define regs_struct directly. This can be removed once we no longer need to 57// support these old Bionic versions and PNaCl toolchain. 58struct regs_struct { 59 long int ebx; 60 long int ecx; 61 long int edx; 62 long int esi; 63 long int edi; 64 long int ebp; 65 long int eax; 66 long int xds; 67 long int xes; 68 long int xfs; 69 long int xgs; 70 long int orig_eax; 71 long int eip; 72 long int xcs; 73 long int eflags; 74 long int esp; 75 long int xss; 76}; 77#else 78typedef user_regs_struct regs_struct; 79#endif 80 81#define SECCOMP_PT_RESULT(_regs) (_regs).eax 82#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_eax 83#define SECCOMP_PT_IP(_regs) (_regs).eip 84#define SECCOMP_PT_PARM1(_regs) (_regs).ebx 85#define SECCOMP_PT_PARM2(_regs) (_regs).ecx 86#define SECCOMP_PT_PARM3(_regs) (_regs).edx 87#define SECCOMP_PT_PARM4(_regs) (_regs).esi 88#define SECCOMP_PT_PARM5(_regs) (_regs).edi 89#define SECCOMP_PT_PARM6(_regs) (_regs).ebp 90 91#elif defined(__x86_64__) 92#define SECCOMP_ARCH AUDIT_ARCH_X86_64 93 94#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)]) 95#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, REG_RAX) 96#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, REG_RAX) 97#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, REG_RIP) 98#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, REG_RDI) 99#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, REG_RSI) 100#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, REG_RDX) 101#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, REG_R10) 102#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, REG_R8) 103#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, REG_R9) 104#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 105#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 106#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 107 instruction_pointer) + 4) 108#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 109 instruction_pointer) + 0) 110#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 111 8*(nr) + 4) 112#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 113 8*(nr) + 0) 114 115typedef user_regs_struct regs_struct; 116#define SECCOMP_PT_RESULT(_regs) (_regs).rax 117#define SECCOMP_PT_SYSCALL(_regs) (_regs).orig_rax 118#define SECCOMP_PT_IP(_regs) (_regs).rip 119#define SECCOMP_PT_PARM1(_regs) (_regs).rdi 120#define SECCOMP_PT_PARM2(_regs) (_regs).rsi 121#define SECCOMP_PT_PARM3(_regs) (_regs).rdx 122#define SECCOMP_PT_PARM4(_regs) (_regs).r10 123#define SECCOMP_PT_PARM5(_regs) (_regs).r8 124#define SECCOMP_PT_PARM6(_regs) (_regs).r9 125 126#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) 127#define SECCOMP_ARCH AUDIT_ARCH_ARM 128 129// ARM sigcontext_t is different from i386/x86_64. 130// See </arch/arm/include/asm/sigcontext.h> in the Linux kernel. 131#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg) 132// ARM EABI syscall convention. 133#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, r0) 134#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, r7) 135#define SECCOMP_IP(_ctx) SECCOMP_REG(_ctx, pc) 136#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, r0) 137#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, r1) 138#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, r2) 139#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, r3) 140#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, r4) 141#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, r5) 142#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 143#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 144#define SECCOMP_IP_MSB_IDX (offsetof(struct arch_seccomp_data, \ 145 instruction_pointer) + 4) 146#define SECCOMP_IP_LSB_IDX (offsetof(struct arch_seccomp_data, \ 147 instruction_pointer) + 0) 148#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 149 8*(nr) + 4) 150#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) + \ 151 8*(nr) + 0) 152 153#if defined(__BIONIC__) || defined(__native_client_nonsfi__) 154// Old Bionic versions and PNaCl toolchain don't have sys/user.h, so we just 155// define regs_struct directly. This can be removed once we no longer need to 156// support these old Bionic versions and PNaCl toolchain. 157struct regs_struct { 158 unsigned long uregs[18]; 159}; 160#else 161typedef user_regs regs_struct; 162#endif 163 164#define REG_cpsr uregs[16] 165#define REG_pc uregs[15] 166#define REG_lr uregs[14] 167#define REG_sp uregs[13] 168#define REG_ip uregs[12] 169#define REG_fp uregs[11] 170#define REG_r10 uregs[10] 171#define REG_r9 uregs[9] 172#define REG_r8 uregs[8] 173#define REG_r7 uregs[7] 174#define REG_r6 uregs[6] 175#define REG_r5 uregs[5] 176#define REG_r4 uregs[4] 177#define REG_r3 uregs[3] 178#define REG_r2 uregs[2] 179#define REG_r1 uregs[1] 180#define REG_r0 uregs[0] 181#define REG_ORIG_r0 uregs[17] 182 183#define SECCOMP_PT_RESULT(_regs) (_regs).REG_r0 184#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_r7 185#define SECCOMP_PT_IP(_regs) (_regs).REG_pc 186#define SECCOMP_PT_PARM1(_regs) (_regs).REG_r0 187#define SECCOMP_PT_PARM2(_regs) (_regs).REG_r1 188#define SECCOMP_PT_PARM3(_regs) (_regs).REG_r2 189#define SECCOMP_PT_PARM4(_regs) (_regs).REG_r3 190#define SECCOMP_PT_PARM5(_regs) (_regs).REG_r4 191#define SECCOMP_PT_PARM6(_regs) (_regs).REG_r5 192 193#elif defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) 194#define SECCOMP_ARCH AUDIT_ARCH_MIPSEL 195#define SYSCALL_EIGHT_ARGS 196// MIPS sigcontext_t is different from i386/x86_64 and ARM. 197// See </arch/mips/include/uapi/asm/sigcontext.h> in the Linux kernel. 198#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[_reg]) 199// Based on MIPS o32 ABI syscall convention. 200// On MIPS, when indirect syscall is being made (syscall(__NR_foo)), 201// real identificator (__NR_foo) is not in v0, but in a0 202#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 2) 203#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 2) 204#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc 205#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 4) 206#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 5) 207#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 6) 208#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 7) 209// Only the first 4 arguments of syscall are in registers. 210// The rest are on the stack. 211#define SECCOMP_STACKPARM(_ctx, n) (((long *)SECCOMP_REG(_ctx, 29))[(n)]) 212#define SECCOMP_PARM5(_ctx) SECCOMP_STACKPARM(_ctx, 4) 213#define SECCOMP_PARM6(_ctx) SECCOMP_STACKPARM(_ctx, 5) 214#define SECCOMP_PARM7(_ctx) SECCOMP_STACKPARM(_ctx, 6) 215#define SECCOMP_PARM8(_ctx) SECCOMP_STACKPARM(_ctx, 7) 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 227// On Mips we don't have structures like user_regs or user_regs_struct in 228// sys/user.h that we could use, so we just define regs_struct directly. 229struct regs_struct { 230 unsigned long long regs[32]; 231}; 232 233#define REG_a3 regs[7] 234#define REG_a2 regs[6] 235#define REG_a1 regs[5] 236#define REG_a0 regs[4] 237#define REG_v1 regs[3] 238#define REG_v0 regs[2] 239 240#define SECCOMP_PT_RESULT(_regs) (_regs).REG_v0 241#define SECCOMP_PT_SYSCALL(_regs) (_regs).REG_v0 242#define SECCOMP_PT_PARM1(_regs) (_regs).REG_a0 243#define SECCOMP_PT_PARM2(_regs) (_regs).REG_a1 244#define SECCOMP_PT_PARM3(_regs) (_regs).REG_a2 245#define SECCOMP_PT_PARM4(_regs) (_regs).REG_a3 246 247#elif defined(__aarch64__) 248struct regs_struct { 249 unsigned long long regs[31]; 250 unsigned long long sp; 251 unsigned long long pc; 252 unsigned long long pstate; 253}; 254 255#define SECCOMP_ARCH AUDIT_ARCH_AARCH64 256 257#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.regs[_reg]) 258 259#define SECCOMP_RESULT(_ctx) SECCOMP_REG(_ctx, 0) 260#define SECCOMP_SYSCALL(_ctx) SECCOMP_REG(_ctx, 8) 261#define SECCOMP_IP(_ctx) (_ctx)->uc_mcontext.pc 262#define SECCOMP_PARM1(_ctx) SECCOMP_REG(_ctx, 0) 263#define SECCOMP_PARM2(_ctx) SECCOMP_REG(_ctx, 1) 264#define SECCOMP_PARM3(_ctx) SECCOMP_REG(_ctx, 2) 265#define SECCOMP_PARM4(_ctx) SECCOMP_REG(_ctx, 3) 266#define SECCOMP_PARM5(_ctx) SECCOMP_REG(_ctx, 4) 267#define SECCOMP_PARM6(_ctx) SECCOMP_REG(_ctx, 5) 268 269#define SECCOMP_NR_IDX (offsetof(struct arch_seccomp_data, nr)) 270#define SECCOMP_ARCH_IDX (offsetof(struct arch_seccomp_data, arch)) 271#define SECCOMP_IP_MSB_IDX \ 272 (offsetof(struct arch_seccomp_data, instruction_pointer) + 4) 273#define SECCOMP_IP_LSB_IDX \ 274 (offsetof(struct arch_seccomp_data, instruction_pointer) + 0) 275#define SECCOMP_ARG_MSB_IDX(nr) \ 276 (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 4) 277#define SECCOMP_ARG_LSB_IDX(nr) \ 278 (offsetof(struct arch_seccomp_data, args) + 8 * (nr) + 0) 279 280#define SECCOMP_PT_RESULT(_regs) (_regs).regs[0] 281#define SECCOMP_PT_SYSCALL(_regs) (_regs).regs[8] 282#define SECCOMP_PT_IP(_regs) (_regs).pc 283#define SECCOMP_PT_PARM1(_regs) (_regs).regs[0] 284#define SECCOMP_PT_PARM2(_regs) (_regs).regs[1] 285#define SECCOMP_PT_PARM3(_regs) (_regs).regs[2] 286#define SECCOMP_PT_PARM4(_regs) (_regs).regs[3] 287#define SECCOMP_PT_PARM5(_regs) (_regs).regs[4] 288#define SECCOMP_PT_PARM6(_regs) (_regs).regs[5] 289#else 290#error Unsupported target platform 291 292#endif 293 294#endif // SANDBOX_LINUX_BPF_DSL_SECCOMP_MACROS_H_ 295