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. 58 struct 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 78 typedef 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 115 typedef 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. 157 struct regs_struct { 158 unsigned long uregs[18]; 159 }; 160 #else 161 typedef 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. 229 struct 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__) 248 struct 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