1*4b9c6d91SCole Faust /* bpf.h
2*4b9c6d91SCole Faust * Copyright 2012 The ChromiumOS Authors
3*4b9c6d91SCole Faust * Use of this source code is governed by a BSD-style license that can be
4*4b9c6d91SCole Faust * found in the LICENSE file.
5*4b9c6d91SCole Faust *
6*4b9c6d91SCole Faust * Berkeley Packet Filter functions.
7*4b9c6d91SCole Faust */
8*4b9c6d91SCole Faust
9*4b9c6d91SCole Faust #ifndef BPF_H
10*4b9c6d91SCole Faust #define BPF_H
11*4b9c6d91SCole Faust
12*4b9c6d91SCole Faust #include <asm/bitsperlong.h> /* for __BITS_PER_LONG */
13*4b9c6d91SCole Faust #include <endian.h>
14*4b9c6d91SCole Faust #include <linux/audit.h>
15*4b9c6d91SCole Faust #include <linux/filter.h>
16*4b9c6d91SCole Faust #include <stddef.h>
17*4b9c6d91SCole Faust #include <sys/user.h>
18*4b9c6d91SCole Faust
19*4b9c6d91SCole Faust #ifdef __cplusplus
20*4b9c6d91SCole Faust extern "C" {
21*4b9c6d91SCole Faust #endif
22*4b9c6d91SCole Faust
23*4b9c6d91SCole Faust #include "arch.h"
24*4b9c6d91SCole Faust
25*4b9c6d91SCole Faust #if __BITS_PER_LONG == 32 || defined(__ILP32__)
26*4b9c6d91SCole Faust #define BITS32
27*4b9c6d91SCole Faust #elif __BITS_PER_LONG == 64
28*4b9c6d91SCole Faust #define BITS64
29*4b9c6d91SCole Faust #endif
30*4b9c6d91SCole Faust
31*4b9c6d91SCole Faust /* Constants for comparison operators. */
32*4b9c6d91SCole Faust #define MIN_OPERATOR 128
33*4b9c6d91SCole Faust enum {
34*4b9c6d91SCole Faust EQ = MIN_OPERATOR,
35*4b9c6d91SCole Faust NE,
36*4b9c6d91SCole Faust LT,
37*4b9c6d91SCole Faust LE,
38*4b9c6d91SCole Faust GT,
39*4b9c6d91SCole Faust GE,
40*4b9c6d91SCole Faust SET,
41*4b9c6d91SCole Faust IN
42*4b9c6d91SCole Faust };
43*4b9c6d91SCole Faust
44*4b9c6d91SCole Faust /*
45*4b9c6d91SCole Faust * BPF return values and data structures,
46*4b9c6d91SCole Faust * since they're not yet in the kernel.
47*4b9c6d91SCole Faust * TODO(crbug.com/1147037): Replace this with an #include.
48*4b9c6d91SCole Faust */
49*4b9c6d91SCole Faust
50*4b9c6d91SCole Faust #define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the entire process */
51*4b9c6d91SCole Faust #define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread */
52*4b9c6d91SCole Faust #define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
53*4b9c6d91SCole Faust #define SECCOMP_RET_TRAP 0x00030000U /* return SIGSYS */
54*4b9c6d91SCole Faust #define SECCOMP_RET_ERRNO 0x00050000U /* return -1 and set errno */
55*4b9c6d91SCole Faust #define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
56*4b9c6d91SCole Faust #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
57*4b9c6d91SCole Faust
58*4b9c6d91SCole Faust #define SECCOMP_RET_DATA 0x0000ffffU /* mask for return value */
59*4b9c6d91SCole Faust
60*4b9c6d91SCole Faust struct seccomp_data {
61*4b9c6d91SCole Faust int nr;
62*4b9c6d91SCole Faust __u32 arch;
63*4b9c6d91SCole Faust __u64 instruction_pointer;
64*4b9c6d91SCole Faust __u64 args[6];
65*4b9c6d91SCole Faust };
66*4b9c6d91SCole Faust
67*4b9c6d91SCole Faust #define syscall_nr (offsetof(struct seccomp_data, nr))
68*4b9c6d91SCole Faust #define arch_nr (offsetof(struct seccomp_data, arch))
69*4b9c6d91SCole Faust
70*4b9c6d91SCole Faust /* Size-dependent defines. */
71*4b9c6d91SCole Faust #if defined(BITS32)
72*4b9c6d91SCole Faust /*
73*4b9c6d91SCole Faust * On 32 bits, comparisons take 2 instructions: 1 for loading the argument,
74*4b9c6d91SCole Faust * 1 for the actual comparison.
75*4b9c6d91SCole Faust */
76*4b9c6d91SCole Faust #define BPF_LOAD_ARG_LEN 1U
77*4b9c6d91SCole Faust #define BPF_COMP_LEN 1U
78*4b9c6d91SCole Faust #define BPF_SHORT_GT_GE_COMP_LEN 1U
79*4b9c6d91SCole Faust #define BPF_GT_GE_COMP_LEN 1U
80*4b9c6d91SCole Faust #define BPF_ARG_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_COMP_LEN)
81*4b9c6d91SCole Faust #define BPF_ARG_SHORT_GT_GE_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_SHORT_GT_GE_COMP_LEN)
82*4b9c6d91SCole Faust #define BPF_ARG_GT_GE_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_GT_GE_COMP_LEN)
83*4b9c6d91SCole Faust
84*4b9c6d91SCole Faust #define bpf_comp_jeq bpf_comp_jeq32
85*4b9c6d91SCole Faust #define bpf_comp_jgt bpf_comp_jgt32
86*4b9c6d91SCole Faust #define bpf_comp_jge bpf_comp_jge32
87*4b9c6d91SCole Faust #define bpf_comp_jset bpf_comp_jset32
88*4b9c6d91SCole Faust
89*4b9c6d91SCole Faust #define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
90*4b9c6d91SCole Faust
91*4b9c6d91SCole Faust #elif defined(BITS64)
92*4b9c6d91SCole Faust /*
93*4b9c6d91SCole Faust * On 64 bits, comparisons take 7-8 instructions: 4 for loading the argument,
94*4b9c6d91SCole Faust * and 3-4 for the actual comparison.
95*4b9c6d91SCole Faust */
96*4b9c6d91SCole Faust #define BPF_LOAD_ARG_LEN 4U
97*4b9c6d91SCole Faust #define BPF_COMP_LEN 3U
98*4b9c6d91SCole Faust #define BPF_SHORT_GT_GE_COMP_LEN 3U
99*4b9c6d91SCole Faust #define BPF_GT_GE_COMP_LEN 4U
100*4b9c6d91SCole Faust #define BPF_ARG_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_COMP_LEN)
101*4b9c6d91SCole Faust #define BPF_ARG_SHORT_GT_GE_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_SHORT_GT_GE_COMP_LEN)
102*4b9c6d91SCole Faust #define BPF_ARG_GT_GE_COMP_LEN (BPF_LOAD_ARG_LEN + BPF_GT_GE_COMP_LEN)
103*4b9c6d91SCole Faust
104*4b9c6d91SCole Faust #define bpf_comp_jeq bpf_comp_jeq64
105*4b9c6d91SCole Faust #define bpf_comp_jgt bpf_comp_jgt64
106*4b9c6d91SCole Faust #define bpf_comp_jge bpf_comp_jge64
107*4b9c6d91SCole Faust #define bpf_comp_jset bpf_comp_jset64
108*4b9c6d91SCole Faust
109*4b9c6d91SCole Faust /* Ensure that we load the logically correct offset. */
110*4b9c6d91SCole Faust #if defined(__LITTLE_ENDIAN__) || __BYTE_ORDER == __LITTLE_ENDIAN
111*4b9c6d91SCole Faust #define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
112*4b9c6d91SCole Faust #define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
113*4b9c6d91SCole Faust #else
114*4b9c6d91SCole Faust #error "Unsupported endianness"
115*4b9c6d91SCole Faust #endif
116*4b9c6d91SCole Faust
117*4b9c6d91SCole Faust #else
118*4b9c6d91SCole Faust #error "Unknown bit width"
119*4b9c6d91SCole Faust
120*4b9c6d91SCole Faust #endif
121*4b9c6d91SCole Faust
122*4b9c6d91SCole Faust /* Common jump targets. */
123*4b9c6d91SCole Faust #define NEXT 0
124*4b9c6d91SCole Faust #define SKIP 1
125*4b9c6d91SCole Faust #define SKIPN(_n) (_n)
126*4b9c6d91SCole Faust
127*4b9c6d91SCole Faust /* Support for labels in BPF programs. */
128*4b9c6d91SCole Faust #define JUMP_JT 0xff
129*4b9c6d91SCole Faust #define JUMP_JF 0xff
130*4b9c6d91SCole Faust #define LABEL_JT 0xfe
131*4b9c6d91SCole Faust #define LABEL_JF 0xfe
132*4b9c6d91SCole Faust
133*4b9c6d91SCole Faust #define MAX_BPF_LABEL_LEN 32
134*4b9c6d91SCole Faust
135*4b9c6d91SCole Faust #define BPF_LABELS_MAX 512U /* Each syscall could have an argument block. */
136*4b9c6d91SCole Faust struct bpf_labels {
137*4b9c6d91SCole Faust size_t count;
138*4b9c6d91SCole Faust struct __bpf_label {
139*4b9c6d91SCole Faust const char *label;
140*4b9c6d91SCole Faust unsigned int location;
141*4b9c6d91SCole Faust } labels[BPF_LABELS_MAX];
142*4b9c6d91SCole Faust };
143*4b9c6d91SCole Faust
144*4b9c6d91SCole Faust /* BPF instruction manipulation functions and macros. */
set_bpf_instr(struct sock_filter * instr,unsigned short code,unsigned int k,unsigned char jt,unsigned char jf)145*4b9c6d91SCole Faust static inline size_t set_bpf_instr(struct sock_filter *instr,
146*4b9c6d91SCole Faust unsigned short code, unsigned int k,
147*4b9c6d91SCole Faust unsigned char jt, unsigned char jf)
148*4b9c6d91SCole Faust {
149*4b9c6d91SCole Faust instr->code = code;
150*4b9c6d91SCole Faust instr->k = k;
151*4b9c6d91SCole Faust instr->jt = jt;
152*4b9c6d91SCole Faust instr->jf = jf;
153*4b9c6d91SCole Faust return 1U;
154*4b9c6d91SCole Faust }
155*4b9c6d91SCole Faust
156*4b9c6d91SCole Faust #define set_bpf_stmt(_block, _code, _k) \
157*4b9c6d91SCole Faust set_bpf_instr((_block), (_code), (_k), 0, 0)
158*4b9c6d91SCole Faust
159*4b9c6d91SCole Faust #define set_bpf_jump(_block, _code, _k, _jt, _jf) \
160*4b9c6d91SCole Faust set_bpf_instr((_block), (_code), (_k), (_jt), (_jf))
161*4b9c6d91SCole Faust
162*4b9c6d91SCole Faust #define set_bpf_lbl(_block, _lbl_id) \
163*4b9c6d91SCole Faust set_bpf_jump((_block), BPF_JMP+BPF_JA, (_lbl_id), \
164*4b9c6d91SCole Faust LABEL_JT, LABEL_JF)
165*4b9c6d91SCole Faust
166*4b9c6d91SCole Faust #define set_bpf_jump_lbl(_block, _lbl_id) \
167*4b9c6d91SCole Faust set_bpf_jump((_block), BPF_JMP+BPF_JA, (_lbl_id), \
168*4b9c6d91SCole Faust JUMP_JT, JUMP_JF)
169*4b9c6d91SCole Faust
170*4b9c6d91SCole Faust #define set_bpf_ret_kill(_block) \
171*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_KILL)
172*4b9c6d91SCole Faust
173*4b9c6d91SCole Faust #define set_bpf_ret_kill_process(_block) \
174*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_KILL_PROCESS)
175*4b9c6d91SCole Faust
176*4b9c6d91SCole Faust #define set_bpf_ret_trap(_block) \
177*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_TRAP)
178*4b9c6d91SCole Faust
179*4b9c6d91SCole Faust #define set_bpf_ret_errno(_block, _errno) \
180*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, \
181*4b9c6d91SCole Faust SECCOMP_RET_ERRNO | ((_errno) & SECCOMP_RET_DATA))
182*4b9c6d91SCole Faust
183*4b9c6d91SCole Faust #define set_bpf_ret_log(_block) \
184*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_LOG)
185*4b9c6d91SCole Faust
186*4b9c6d91SCole Faust #define set_bpf_ret_allow(_block) \
187*4b9c6d91SCole Faust set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
188*4b9c6d91SCole Faust
189*4b9c6d91SCole Faust #define bpf_load_syscall_nr(_filter) \
190*4b9c6d91SCole Faust set_bpf_stmt((_filter), BPF_LD+BPF_W+BPF_ABS, syscall_nr)
191*4b9c6d91SCole Faust
192*4b9c6d91SCole Faust /* BPF label functions. */
193*4b9c6d91SCole Faust int bpf_resolve_jumps(struct bpf_labels *labels,
194*4b9c6d91SCole Faust struct sock_filter *filter, size_t count);
195*4b9c6d91SCole Faust int bpf_label_id(struct bpf_labels *labels, const char *label);
196*4b9c6d91SCole Faust void free_label_strings(struct bpf_labels *labels);
197*4b9c6d91SCole Faust
198*4b9c6d91SCole Faust /* BPF helper functions. */
199*4b9c6d91SCole Faust size_t bpf_load_arg(struct sock_filter *filter, int argidx);
200*4b9c6d91SCole Faust size_t bpf_comp_jeq(struct sock_filter *filter, unsigned long c,
201*4b9c6d91SCole Faust unsigned char jt, unsigned char jf);
202*4b9c6d91SCole Faust size_t bpf_comp_jgt(struct sock_filter *filter, unsigned long c,
203*4b9c6d91SCole Faust unsigned char jt, unsigned char jf);
204*4b9c6d91SCole Faust size_t bpf_comp_jge(struct sock_filter *filter, unsigned long c,
205*4b9c6d91SCole Faust unsigned char jt, unsigned char jf);
206*4b9c6d91SCole Faust size_t bpf_comp_jset(struct sock_filter *filter, unsigned long mask,
207*4b9c6d91SCole Faust unsigned char jt, unsigned char jf);
208*4b9c6d91SCole Faust size_t bpf_comp_jin(struct sock_filter *filter, unsigned long mask,
209*4b9c6d91SCole Faust unsigned char jt, unsigned char jf);
210*4b9c6d91SCole Faust
211*4b9c6d91SCole Faust /* Functions called by syscall_filter.c */
212*4b9c6d91SCole Faust #define ARCH_VALIDATION_LEN 3U
213*4b9c6d91SCole Faust #define ALLOW_SYSCALL_LEN 2U
214*4b9c6d91SCole Faust
215*4b9c6d91SCole Faust size_t bpf_arg_comp(struct sock_filter **pfilter,
216*4b9c6d91SCole Faust int op, int argidx, unsigned long c, unsigned int label_id);
217*4b9c6d91SCole Faust size_t bpf_validate_arch(struct sock_filter *filter);
218*4b9c6d91SCole Faust size_t bpf_allow_syscall(struct sock_filter *filter, int nr);
219*4b9c6d91SCole Faust size_t bpf_allow_syscall_args(struct sock_filter *filter,
220*4b9c6d91SCole Faust int nr, unsigned int id);
221*4b9c6d91SCole Faust
222*4b9c6d91SCole Faust #ifdef __cplusplus
223*4b9c6d91SCole Faust }; /* extern "C" */
224*4b9c6d91SCole Faust #endif
225*4b9c6d91SCole Faust
226*4b9c6d91SCole Faust #endif /* BPF_H */
227