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