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// For audit.h
20#ifndef EM_ARM
21#define EM_ARM    40
22#endif
23#ifndef EM_386
24#define EM_386    3
25#endif
26#ifndef EM_X86_64
27#define EM_X86_64 62
28#endif
29
30#ifndef __AUDIT_ARCH_64BIT
31#define __AUDIT_ARCH_64BIT 0x80000000
32#endif
33#ifndef __AUDIT_ARCH_LE
34#define __AUDIT_ARCH_LE    0x40000000
35#endif
36#ifndef AUDIT_ARCH_ARM
37#define AUDIT_ARCH_ARM    (EM_ARM|__AUDIT_ARCH_LE)
38#endif
39#ifndef AUDIT_ARCH_I386
40#define AUDIT_ARCH_I386   (EM_386|__AUDIT_ARCH_LE)
41#endif
42#ifndef AUDIT_ARCH_X86_64
43#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
44#endif
45
46// For prctl.h
47#ifndef PR_SET_SECCOMP
48#define PR_SET_SECCOMP               22
49#define PR_GET_SECCOMP               21
50#endif
51#ifndef PR_SET_NO_NEW_PRIVS
52#define PR_SET_NO_NEW_PRIVS          38
53#define PR_GET_NO_NEW_PRIVS          39
54#endif
55#ifndef IPC_64
56#define IPC_64                   0x0100
57#endif
58
59#ifndef BPF_MOD
60#define BPF_MOD                    0x90
61#endif
62#ifndef BPF_XOR
63#define BPF_XOR                    0xA0
64#endif
65
66// In order to build will older tool chains, we currently have to avoid
67// including <linux/seccomp.h>. Until that can be fixed (if ever). Rely on
68// our own definitions of the seccomp kernel ABI.
69#ifndef SECCOMP_MODE_FILTER
70#define SECCOMP_MODE_DISABLED         0
71#define SECCOMP_MODE_STRICT           1
72#define SECCOMP_MODE_FILTER           2  // User user-supplied filter
73#endif
74
75#ifndef SECCOMP_RET_KILL
76// Return values supported for BPF filter programs. Please note that the
77// "illegal" SECCOMP_RET_INVALID is not supported by the kernel, should only
78// ever be used internally, and would result in the kernel killing our process.
79#define SECCOMP_RET_KILL    0x00000000U  // Kill the task immediately
80#define SECCOMP_RET_INVALID 0x00010000U  // Illegal return value
81#define SECCOMP_RET_TRAP    0x00030000U  // Disallow and force a SIGSYS
82#define SECCOMP_RET_ERRNO   0x00050000U  // Returns an errno
83#define SECCOMP_RET_TRACE   0x7ff00000U  // Pass to a tracer or disallow
84#define SECCOMP_RET_ALLOW   0x7fff0000U  // Allow
85#define SECCOMP_RET_ACTION  0xffff0000U  // Masks for the return value
86#define SECCOMP_RET_DATA    0x0000ffffU  //   sections
87#else
88#define SECCOMP_RET_INVALID 0x00010000U  // Illegal return value
89#endif
90
91#ifndef SYS_SECCOMP
92#define SYS_SECCOMP                   1
93#endif
94
95// Impose some reasonable maximum BPF program size. Realistically, the
96// kernel probably has much lower limits. But by limiting to less than
97// 30 bits, we can ease requirements on some of our data types.
98#define SECCOMP_MAX_PROGRAM_SIZE (1<<30)
99
100#if defined(__i386__)
101#define MIN_SYSCALL         0u
102#define MAX_PUBLIC_SYSCALL  1024u
103#define MAX_SYSCALL         MAX_PUBLIC_SYSCALL
104#define SECCOMP_ARCH        AUDIT_ARCH_I386
105
106#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
107#define SECCOMP_RESULT(_ctx)    SECCOMP_REG(_ctx, REG_EAX)
108#define SECCOMP_SYSCALL(_ctx)   SECCOMP_REG(_ctx, REG_EAX)
109#define SECCOMP_IP(_ctx)        SECCOMP_REG(_ctx, REG_EIP)
110#define SECCOMP_PARM1(_ctx)     SECCOMP_REG(_ctx, REG_EBX)
111#define SECCOMP_PARM2(_ctx)     SECCOMP_REG(_ctx, REG_ECX)
112#define SECCOMP_PARM3(_ctx)     SECCOMP_REG(_ctx, REG_EDX)
113#define SECCOMP_PARM4(_ctx)     SECCOMP_REG(_ctx, REG_ESI)
114#define SECCOMP_PARM5(_ctx)     SECCOMP_REG(_ctx, REG_EDI)
115#define SECCOMP_PARM6(_ctx)     SECCOMP_REG(_ctx, REG_EBP)
116#define SECCOMP_NR_IDX          (offsetof(struct arch_seccomp_data, nr))
117#define SECCOMP_ARCH_IDX        (offsetof(struct arch_seccomp_data, arch))
118#define SECCOMP_IP_MSB_IDX      (offsetof(struct arch_seccomp_data,           \
119                                          instruction_pointer) + 4)
120#define SECCOMP_IP_LSB_IDX      (offsetof(struct arch_seccomp_data,           \
121                                          instruction_pointer) + 0)
122#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
123                                 8*(nr) + 4)
124#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
125                                 8*(nr) + 0)
126
127#elif defined(__x86_64__)
128#define MIN_SYSCALL         0u
129#define MAX_PUBLIC_SYSCALL  1024u
130#define MAX_SYSCALL         MAX_PUBLIC_SYSCALL
131#define SECCOMP_ARCH        AUDIT_ARCH_X86_64
132
133#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.gregs[(_reg)])
134#define SECCOMP_RESULT(_ctx)    SECCOMP_REG(_ctx, REG_RAX)
135#define SECCOMP_SYSCALL(_ctx)   SECCOMP_REG(_ctx, REG_RAX)
136#define SECCOMP_IP(_ctx)        SECCOMP_REG(_ctx, REG_RIP)
137#define SECCOMP_PARM1(_ctx)     SECCOMP_REG(_ctx, REG_RDI)
138#define SECCOMP_PARM2(_ctx)     SECCOMP_REG(_ctx, REG_RSI)
139#define SECCOMP_PARM3(_ctx)     SECCOMP_REG(_ctx, REG_RDX)
140#define SECCOMP_PARM4(_ctx)     SECCOMP_REG(_ctx, REG_R10)
141#define SECCOMP_PARM5(_ctx)     SECCOMP_REG(_ctx, REG_R8)
142#define SECCOMP_PARM6(_ctx)     SECCOMP_REG(_ctx, REG_R9)
143#define SECCOMP_NR_IDX          (offsetof(struct arch_seccomp_data, nr))
144#define SECCOMP_ARCH_IDX        (offsetof(struct arch_seccomp_data, arch))
145#define SECCOMP_IP_MSB_IDX      (offsetof(struct arch_seccomp_data,           \
146                                          instruction_pointer) + 4)
147#define SECCOMP_IP_LSB_IDX      (offsetof(struct arch_seccomp_data,           \
148                                          instruction_pointer) + 0)
149#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
150                                 8*(nr) + 4)
151#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
152                                 8*(nr) + 0)
153
154#elif defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__))
155// ARM EABI includes "ARM private" system calls starting at |__ARM_NR_BASE|,
156// and a "ghost syscall private to the kernel", cmpxchg,
157// at |__ARM_NR_BASE+0x00fff0|.
158// See </arch/arm/include/asm/unistd.h> in the Linux kernel.
159#define MIN_SYSCALL         ((unsigned int)__NR_SYSCALL_BASE)
160#define MAX_PUBLIC_SYSCALL  (MIN_SYSCALL + 1024u)
161#define MIN_PRIVATE_SYSCALL ((unsigned int)__ARM_NR_BASE)
162#define MAX_PRIVATE_SYSCALL (MIN_PRIVATE_SYSCALL + 16u)
163#define MIN_GHOST_SYSCALL   ((unsigned int)__ARM_NR_BASE + 0xfff0u)
164#define MAX_SYSCALL         (MIN_GHOST_SYSCALL + 4u)
165
166#define SECCOMP_ARCH AUDIT_ARCH_ARM
167
168// ARM sigcontext_t is different from i386/x86_64.
169// See </arch/arm/include/asm/sigcontext.h> in the Linux kernel.
170#define SECCOMP_REG(_ctx, _reg) ((_ctx)->uc_mcontext.arm_##_reg)
171// ARM EABI syscall convention.
172#define SECCOMP_RESULT(_ctx)    SECCOMP_REG(_ctx, r0)
173#define SECCOMP_SYSCALL(_ctx)   SECCOMP_REG(_ctx, r7)
174#define SECCOMP_IP(_ctx)        SECCOMP_REG(_ctx, pc)
175#define SECCOMP_PARM1(_ctx)     SECCOMP_REG(_ctx, r0)
176#define SECCOMP_PARM2(_ctx)     SECCOMP_REG(_ctx, r1)
177#define SECCOMP_PARM3(_ctx)     SECCOMP_REG(_ctx, r2)
178#define SECCOMP_PARM4(_ctx)     SECCOMP_REG(_ctx, r3)
179#define SECCOMP_PARM5(_ctx)     SECCOMP_REG(_ctx, r4)
180#define SECCOMP_PARM6(_ctx)     SECCOMP_REG(_ctx, r5)
181#define SECCOMP_NR_IDX          (offsetof(struct arch_seccomp_data, nr))
182#define SECCOMP_ARCH_IDX        (offsetof(struct arch_seccomp_data, arch))
183#define SECCOMP_IP_MSB_IDX      (offsetof(struct arch_seccomp_data,           \
184                                          instruction_pointer) + 4)
185#define SECCOMP_IP_LSB_IDX      (offsetof(struct arch_seccomp_data,           \
186                                          instruction_pointer) + 0)
187#define SECCOMP_ARG_MSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
188                                 8*(nr) + 4)
189#define SECCOMP_ARG_LSB_IDX(nr) (offsetof(struct arch_seccomp_data, args) +   \
190                                 8*(nr) + 0)
191
192#else
193#error Unsupported target platform
194
195#endif
196
197#endif  // SANDBOX_LINUX_SECCOMP_BPF_LINUX_SECCOMP_H__
198