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