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