2014-12-02 02:06:37 +03:00
# ifndef __BPF_HELPERS_H
# define __BPF_HELPERS_H
/* helper macro to place programs, maps, license in
* different sections in elf_bpf file . Section names
* are interpreted by elf_bpf loader
*/
# define SEC(NAME) __attribute__((section(NAME), used))
/* helper functions called from eBPF programs written in C */
static void * ( * bpf_map_lookup_elem ) ( void * map , void * key ) =
( void * ) BPF_FUNC_map_lookup_elem ;
static int ( * bpf_map_update_elem ) ( void * map , void * key , void * value ,
unsigned long long flags ) =
( void * ) BPF_FUNC_map_update_elem ;
static int ( * bpf_map_delete_elem ) ( void * map , void * key ) =
( void * ) BPF_FUNC_map_delete_elem ;
2015-03-25 22:49:23 +03:00
static int ( * bpf_probe_read ) ( void * dst , int size , void * unsafe_ptr ) =
( void * ) BPF_FUNC_probe_read ;
static unsigned long long ( * bpf_ktime_get_ns ) ( void ) =
( void * ) BPF_FUNC_ktime_get_ns ;
static int ( * bpf_trace_printk ) ( const char * fmt , int fmt_size , . . . ) =
( void * ) BPF_FUNC_trace_printk ;
samples/bpf: bpf_tail_call example for tracing
kprobe example that demonstrates how future seccomp programs may look like.
It attaches to seccomp_phase1() function and tail-calls other BPF programs
depending on syscall number.
Existing optimized classic BPF seccomp programs generated by Chrome look like:
if (sd.nr < 121) {
if (sd.nr < 57) {
if (sd.nr < 22) {
if (sd.nr < 7) {
if (sd.nr < 4) {
if (sd.nr < 1) {
check sys_read
} else {
if (sd.nr < 3) {
check sys_write and sys_open
} else {
check sys_close
}
}
} else {
} else {
} else {
} else {
} else {
}
the future seccomp using native eBPF may look like:
bpf_tail_call(&sd, &syscall_jmp_table, sd.nr);
which is simpler, faster and leaves more room for per-syscall checks.
Usage:
$ sudo ./tracex5
<...>-366 [001] d... 4.870033: : read(fd=1, buf=00007f6d5bebf000, size=771)
<...>-369 [003] d... 4.870066: : mmap
<...>-369 [003] d... 4.870077: : syscall=110 (one of get/set uid/pid/gid)
<...>-369 [003] d... 4.870089: : syscall=107 (one of get/set uid/pid/gid)
sh-369 [000] d... 4.891740: : read(fd=0, buf=00000000023d1000, size=512)
sh-369 [000] d... 4.891747: : write(fd=1, buf=00000000023d3000, size=512)
sh-369 [000] d... 4.891747: : read(fd=1, buf=00000000023d3000, size=512)
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2015-05-20 02:59:05 +03:00
static void ( * bpf_tail_call ) ( void * ctx , void * map , int index ) =
( void * ) BPF_FUNC_tail_call ;
2015-05-20 02:59:06 +03:00
static unsigned long long ( * bpf_get_smp_processor_id ) ( void ) =
( void * ) BPF_FUNC_get_smp_processor_id ;
2015-06-13 05:39:12 +03:00
static unsigned long long ( * bpf_get_current_pid_tgid ) ( void ) =
( void * ) BPF_FUNC_get_current_pid_tgid ;
static unsigned long long ( * bpf_get_current_uid_gid ) ( void ) =
( void * ) BPF_FUNC_get_current_uid_gid ;
static int ( * bpf_get_current_comm ) ( void * buf , int buf_size ) =
( void * ) BPF_FUNC_get_current_comm ;
2015-08-06 10:02:36 +03:00
static int ( * bpf_perf_event_read ) ( void * map , int index ) =
( void * ) BPF_FUNC_perf_event_read ;
2015-09-16 09:05:43 +03:00
static int ( * bpf_clone_redirect ) ( void * ctx , int ifindex , int flags ) =
( void * ) BPF_FUNC_clone_redirect ;
static int ( * bpf_redirect ) ( int ifindex , int flags ) =
( void * ) BPF_FUNC_redirect ;
2016-08-10 19:45:39 +03:00
static int ( * bpf_perf_event_output ) ( void * ctx , void * map ,
unsigned long long flags , void * data ,
int size ) =
2015-10-21 06:02:35 +03:00
( void * ) BPF_FUNC_perf_event_output ;
2016-02-18 06:58:59 +03:00
static int ( * bpf_get_stackid ) ( void * ctx , void * map , int flags ) =
( void * ) BPF_FUNC_get_stackid ;
2016-07-25 15:54:46 +03:00
static int ( * bpf_probe_write_user ) ( void * dst , void * src , int size ) =
( void * ) BPF_FUNC_probe_write_user ;
2016-08-12 18:57:04 +03:00
static int ( * bpf_current_task_under_cgroup ) ( void * map , int index ) =
( void * ) BPF_FUNC_current_task_under_cgroup ;
2016-08-19 21:55:44 +03:00
static int ( * bpf_skb_get_tunnel_key ) ( void * ctx , void * key , int size , int flags ) =
( void * ) BPF_FUNC_skb_get_tunnel_key ;
static int ( * bpf_skb_set_tunnel_key ) ( void * ctx , void * key , int size , int flags ) =
( void * ) BPF_FUNC_skb_set_tunnel_key ;
static int ( * bpf_skb_get_tunnel_opt ) ( void * ctx , void * md , int size ) =
( void * ) BPF_FUNC_skb_get_tunnel_opt ;
static int ( * bpf_skb_set_tunnel_opt ) ( void * ctx , void * md , int size ) =
( void * ) BPF_FUNC_skb_set_tunnel_opt ;
2016-09-02 04:37:25 +03:00
static unsigned long long ( * bpf_get_prandom_u32 ) ( void ) =
( void * ) BPF_FUNC_get_prandom_u32 ;
2016-12-08 02:53:14 +03:00
static int ( * bpf_xdp_adjust_head ) ( void * ctx , int offset ) =
( void * ) BPF_FUNC_xdp_adjust_head ;
2014-12-02 02:06:37 +03:00
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
*/
struct sk_buff ;
unsigned long long load_byte ( void * skb ,
unsigned long long off ) asm ( " llvm.bpf.load.byte " ) ;
unsigned long long load_half ( void * skb ,
unsigned long long off ) asm ( " llvm.bpf.load.half " ) ;
unsigned long long load_word ( void * skb ,
unsigned long long off ) asm ( " llvm.bpf.load.word " ) ;
/* a helper structure used by eBPF C program
* to describe map attributes to elf_bpf loader
*/
struct bpf_map_def {
unsigned int type ;
unsigned int key_size ;
unsigned int value_size ;
unsigned int max_entries ;
2016-03-08 08:57:20 +03:00
unsigned int map_flags ;
2014-12-02 02:06:37 +03:00
} ;
2016-11-30 19:10:11 +03:00
static int ( * bpf_skb_load_bytes ) ( void * ctx , int off , void * to , int len ) =
( void * ) BPF_FUNC_skb_load_bytes ;
2015-04-02 03:12:13 +03:00
static int ( * bpf_skb_store_bytes ) ( void * ctx , int off , void * from , int len , int flags ) =
( void * ) BPF_FUNC_skb_store_bytes ;
static int ( * bpf_l3_csum_replace ) ( void * ctx , int off , int from , int to , int flags ) =
( void * ) BPF_FUNC_l3_csum_replace ;
static int ( * bpf_l4_csum_replace ) ( void * ctx , int off , int from , int to , int flags ) =
( void * ) BPF_FUNC_l4_csum_replace ;
2016-08-12 23:17:17 +03:00
static int ( * bpf_skb_under_cgroup ) ( void * ctx , void * map , int index ) =
( void * ) BPF_FUNC_skb_under_cgroup ;
2016-11-30 19:10:11 +03:00
static int ( * bpf_skb_change_head ) ( void * , int len , int flags ) =
( void * ) BPF_FUNC_skb_change_head ;
2015-04-02 03:12:13 +03:00
2015-07-06 17:20:07 +03:00
# if defined(__x86_64__)
# define PT_REGS_PARM1(x) ((x)->di)
# define PT_REGS_PARM2(x) ((x)->si)
# define PT_REGS_PARM3(x) ((x)->dx)
# define PT_REGS_PARM4(x) ((x)->cx)
# define PT_REGS_PARM5(x) ((x)->r8)
# define PT_REGS_RET(x) ((x)->sp)
# define PT_REGS_FP(x) ((x)->bp)
# define PT_REGS_RC(x) ((x)->ax)
# define PT_REGS_SP(x) ((x)->sp)
2016-04-04 20:01:34 +03:00
# define PT_REGS_IP(x) ((x)->ip)
2015-07-06 17:20:07 +03:00
# elif defined(__s390x__)
# define PT_REGS_PARM1(x) ((x)->gprs[2])
# define PT_REGS_PARM2(x) ((x)->gprs[3])
# define PT_REGS_PARM3(x) ((x)->gprs[4])
# define PT_REGS_PARM4(x) ((x)->gprs[5])
# define PT_REGS_PARM5(x) ((x)->gprs[6])
# define PT_REGS_RET(x) ((x)->gprs[14])
# define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
# define PT_REGS_RC(x) ((x)->gprs[2])
# define PT_REGS_SP(x) ((x)->gprs[15])
2016-11-28 15:48:30 +03:00
# define PT_REGS_IP(x) ((x)->psw.addr)
2015-07-06 17:20:07 +03:00
2015-10-27 03:02:19 +03:00
# elif defined(__aarch64__)
# define PT_REGS_PARM1(x) ((x)->regs[0])
# define PT_REGS_PARM2(x) ((x)->regs[1])
# define PT_REGS_PARM3(x) ((x)->regs[2])
# define PT_REGS_PARM4(x) ((x)->regs[3])
# define PT_REGS_PARM5(x) ((x)->regs[4])
# define PT_REGS_RET(x) ((x)->regs[30])
# define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */
# define PT_REGS_RC(x) ((x)->regs[0])
# define PT_REGS_SP(x) ((x)->sp)
2016-04-04 20:01:34 +03:00
# define PT_REGS_IP(x) ((x)->pc)
# elif defined(__powerpc__)
# define PT_REGS_PARM1(x) ((x)->gpr[3])
# define PT_REGS_PARM2(x) ((x)->gpr[4])
# define PT_REGS_PARM3(x) ((x)->gpr[5])
# define PT_REGS_PARM4(x) ((x)->gpr[6])
# define PT_REGS_PARM5(x) ((x)->gpr[7])
# define PT_REGS_RC(x) ((x)->gpr[3])
# define PT_REGS_SP(x) ((x)->sp)
# define PT_REGS_IP(x) ((x)->nip)
2015-10-27 03:02:19 +03:00
2015-07-06 17:20:07 +03:00
# endif
2016-04-04 20:01:34 +03:00
# ifdef __powerpc__
# define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; })
# define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
# else
# define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ \
bpf_probe_read ( & ( ip ) , sizeof ( ip ) , ( void * ) PT_REGS_RET ( ctx ) ) ; } )
# define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ \
bpf_probe_read ( & ( ip ) , sizeof ( ip ) , \
( void * ) ( PT_REGS_FP ( ctx ) + sizeof ( ip ) ) ) ; } )
# endif
2014-12-02 02:06:37 +03:00
# endif