code-intelligence.com/cifuzz@v0.40.0/third-party/minijail/bpf.h (about)

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