2019-01-26 02:24:44 +03:00
{
" calls: basic sanity " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. result = ACCEPT ,
} ,
{
" calls: not on unpriviledged " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. errstr_unpriv = " function calls to other bpf functions are allowed for root only " ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
. retval = 1 ,
} ,
{
" calls: div by 0 in subprog " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 8 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_1 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_0 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , 8 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_2 , BPF_REG_1 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_0 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV32_IMM ( BPF_REG_2 , 0 ) ,
BPF_MOV32_IMM ( BPF_REG_3 , 1 ) ,
BPF_ALU32_REG ( BPF_DIV , BPF_REG_3 , BPF_REG_2 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 1 ,
} ,
{
" calls: multiple ret types in subprog 1 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 8 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_1 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_0 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , 8 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_2 , BPF_REG_1 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_0 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 1 ) ,
BPF_MOV32_IMM ( BPF_REG_0 , 42 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = REJECT ,
. errstr = " R0 invalid mem access 'inv' " ,
} ,
{
" calls: multiple ret types in subprog 2 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 8 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_1 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_0 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , 8 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_2 , BPF_REG_1 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_0 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 9 ) ,
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 1 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_6 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 64 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 16 } ,
. result = REJECT ,
. errstr = " R0 min value is outside of the array range " ,
} ,
{
" calls: overlapping caller/callee " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " last insn is not an exit or jmp " ,
. result = REJECT ,
} ,
{
" calls: wrong recursive calls " ,
. insns = {
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 4 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " jump out of range " ,
. result = REJECT ,
} ,
{
" calls: wrong src reg " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 2 , 0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " BPF_CALL uses reserved fields " ,
. result = REJECT ,
} ,
{
" calls: wrong off value " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , - 1 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " BPF_CALL uses reserved fields " ,
. result = REJECT ,
} ,
{
" calls: jump back loop " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 1 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " back-edge from insn 0 to 0 " ,
. result = REJECT ,
} ,
{
" calls: conditional call " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " jump out of range " ,
. result = REJECT ,
} ,
{
" calls: conditional call 2 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. result = ACCEPT ,
} ,
{
" calls: conditional call 3 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 3 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 4 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 6 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 3 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 6 ) ,
} ,
2019-06-15 22:12:22 +03:00
. prog_type = BPF_PROG_TYPE_SOCKET_FILTER ,
. errstr_unpriv = " back-edge from insn " ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
. retval = 1 ,
2019-01-26 02:24:44 +03:00
} ,
{
" calls: conditional call 4 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 5 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. result = ACCEPT ,
} ,
{
" calls: conditional call 5 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 6 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
2019-06-15 22:12:22 +03:00
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 1 ,
2019-01-26 02:24:44 +03:00
} ,
{
" calls: conditional call 6 " ,
. insns = {
2019-06-15 22:12:22 +03:00
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
2019-01-26 02:24:44 +03:00
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
2019-06-15 22:12:22 +03:00
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , - 3 ) ,
2019-01-26 02:24:44 +03:00
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , mark ) ) ,
BPF_EXIT_INSN ( ) ,
} ,
2019-06-15 22:12:22 +03:00
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " infinite loop detected " ,
2019-01-26 02:24:44 +03:00
. result = REJECT ,
} ,
{
" calls: using r0 returned by callee " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. result = ACCEPT ,
} ,
{
" calls: using uninit r0 from callee " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " !read_ok " ,
. result = REJECT ,
} ,
{
" calls: callee is using r1 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_ACT ,
. result = ACCEPT ,
. retval = TEST_DATA_LEN ,
} ,
{
" calls: callee using args1 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. errstr_unpriv = " allowed for root only " ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
. retval = POINTER_VALUE ,
} ,
{
" calls: callee using wrong args2 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " R2 !read_ok " ,
. result = REJECT ,
} ,
{
" calls: callee using two args " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_1 , BPF_REG_6 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_6 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_1 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_0 , BPF_REG_2 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. errstr_unpriv = " allowed for root only " ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
. retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN ,
} ,
{
" calls: callee changing pkt pointers " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_6 , BPF_REG_1 , offsetof ( struct xdp_md , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_7 , BPF_REG_1 ,
offsetof ( struct xdp_md , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_8 , BPF_REG_6 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_8 , 8 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_8 , BPF_REG_7 , 2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
/* clear_all_pkt_pointers() has to walk all frames
* to make sure that pkt pointers in the caller
* are cleared when callee is calling a helper that
* adjusts packet size
*/
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_6 , 0 ) ,
BPF_MOV32_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_2 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_xdp_adjust_head ) ,
BPF_EXIT_INSN ( ) ,
} ,
. result = REJECT ,
. errstr = " R6 invalid mem access 'inv' " ,
. prog_type = BPF_PROG_TYPE_XDP ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
2019-04-24 22:51:26 +03:00
{
" calls: ptr null check in subprog " ,
. insns = {
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_EMIT_CALL ( BPF_FUNC_map_lookup_elem ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_0 , BPF_REG_6 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. errstr_unpriv = " function calls to other bpf functions are allowed for root only " ,
. fixup_map_hash_48b = { 3 } ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
. retval = 0 ,
} ,
2019-01-26 02:24:44 +03:00
{
" calls: two calls with args " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_7 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = TEST_DATA_LEN + TEST_DATA_LEN ,
} ,
{
" calls: calls with stack arith " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 64 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 64 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 64 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 42 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_2 , BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 42 ,
} ,
{
" calls: calls with misaligned stack access " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 63 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 61 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 63 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 42 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_2 , BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. flags = F_LOAD_WITH_STRICT_ALIGNMENT ,
. errstr = " misaligned stack access " ,
. result = REJECT ,
} ,
{
" calls: calls control flow, jump test " ,
. insns = {
BPF_MOV64_IMM ( BPF_REG_0 , 42 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 43 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 43 ,
} ,
{
" calls: calls control flow, jump test 2 " ,
. insns = {
BPF_MOV64_IMM ( BPF_REG_0 , 42 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 43 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " jump out of range from insn 1 to 4 " ,
. result = REJECT ,
} ,
{
" calls: two calls with bad jump " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_7 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , - 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " jump out of range from insn 11 to 9 " ,
. result = REJECT ,
} ,
{
" calls: recursive call. test1 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 1 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " back-edge " ,
. result = REJECT ,
} ,
{
" calls: recursive call. test2 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " back-edge " ,
. result = REJECT ,
} ,
{
" calls: unreachable code " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " unreachable insn 6 " ,
. result = REJECT ,
} ,
{
" calls: invalid call " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 4 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " invalid destination " ,
. result = REJECT ,
} ,
{
" calls: invalid call 2 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 0x7fffffff ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " invalid destination " ,
. result = REJECT ,
} ,
{
" calls: jumping across function bodies. test1 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , - 3 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " jump out of range " ,
. result = REJECT ,
} ,
{
" calls: jumping across function bodies. test2 " ,
. insns = {
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " jump out of range " ,
. result = REJECT ,
} ,
{
" calls: call without exit " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , - 2 ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " not an exit " ,
. result = REJECT ,
} ,
{
" calls: call into middle of ld_imm64 " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LD_IMM64 ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " last insn " ,
. result = REJECT ,
} ,
{
" calls: call into middle of other call " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " last insn " ,
. result = REJECT ,
} ,
{
" calls: ld_abs with changing ctx data in callee " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_LD_ABS ( BPF_B , 0 ) ,
BPF_LD_ABS ( BPF_H , 0 ) ,
BPF_LD_ABS ( BPF_W , 0 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 5 ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_7 ) ,
BPF_LD_ABS ( BPF_B , 0 ) ,
BPF_LD_ABS ( BPF_H , 0 ) ,
BPF_LD_ABS ( BPF_W , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_IMM ( BPF_REG_2 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_3 , 2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_skb_vlan_push ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " BPF_LD_[ABS|IND] instructions cannot be mixed " ,
. result = REJECT ,
} ,
{
" calls: two calls with bad fallthrough " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_0 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 ,
offsetof ( struct __sk_buff , len ) ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_TRACEPOINT ,
. errstr = " not an exit " ,
. result = REJECT ,
} ,
{
" calls: two calls with stack read " ,
. insns = {
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_7 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_7 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. result = ACCEPT ,
} ,
{
" calls: two calls with stack write " ,
. insns = {
/* main prog */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_10 , - 16 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 7 ) ,
BPF_MOV64_REG ( BPF_REG_8 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_ALU64_REG ( BPF_ADD , BPF_REG_8 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_8 ) ,
/* write into stack frame of main prog */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* read from stack frame of main prog */
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_1 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. result = ACCEPT ,
} ,
{
" calls: stack overflow using two frames (pre-call access) " ,
. insns = {
/* prog 1 */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* prog 2 */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " combined stack size " ,
. result = REJECT ,
} ,
{
" calls: stack overflow using two frames (post-call access) " ,
. insns = {
/* prog 1 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* prog 2 */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " combined stack size " ,
. result = REJECT ,
} ,
{
" calls: stack depth check using three frames. test1 " ,
. insns = {
/* main */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) , /* call A */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 5 ) , /* call B */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 32 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* A */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 256 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* B */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 3 ) , /* call A */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 64 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
/* stack_main=32, stack_A=256, stack_B=64
* and max ( main + A , main + A + B ) < 512
*/
. result = ACCEPT ,
} ,
{
" calls: stack depth check using three frames. test2 " ,
. insns = {
/* main */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) , /* call A */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 5 ) , /* call B */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 32 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* A */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 64 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* B */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 3 ) , /* call A */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 256 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
/* stack_main=32, stack_A=64, stack_B=256
* and max ( main + A , main + A + B ) < 512
*/
. result = ACCEPT ,
} ,
{
" calls: stack depth check using three frames. test3 " ,
. insns = {
/* main */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) , /* call A */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 8 ) , /* call B */
BPF_JMP_IMM ( BPF_JGE , BPF_REG_6 , 0 , 1 ) ,
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 64 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* A */
BPF_JMP_IMM ( BPF_JLT , BPF_REG_1 , 10 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 224 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 3 ) ,
/* B */
BPF_JMP_IMM ( BPF_JGT , BPF_REG_1 , 2 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , - 6 ) , /* call A */
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 256 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
/* stack_main=64, stack_A=224, stack_B=256
* and max ( main + A , main + A + B ) > 512
*/
. errstr = " combined stack " ,
. result = REJECT ,
} ,
{
" calls: stack depth check using three frames. test4 " ,
/* void main(void) {
* func1 ( 0 ) ;
* func1 ( 1 ) ;
* func2 ( 1 ) ;
* }
* void func1 ( int alloc_or_recurse ) {
* if ( alloc_or_recurse ) {
* frame_pointer [ - 300 ] = 1 ;
* } else {
* func2 ( alloc_or_recurse ) ;
* }
* }
* void func2 ( int alloc_or_recurse ) {
* if ( alloc_or_recurse ) {
* frame_pointer [ - 300 ] = 1 ;
* }
* }
*/
. insns = {
/* main */
BPF_MOV64_IMM ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 6 ) , /* call A */
BPF_MOV64_IMM ( BPF_REG_1 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) , /* call A */
BPF_MOV64_IMM ( BPF_REG_1 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 7 ) , /* call B */
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* A */
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 2 ) ,
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call B */
BPF_EXIT_INSN ( ) ,
/* B */
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 1 ) ,
BPF_ST_MEM ( BPF_B , BPF_REG_10 , - 300 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. result = REJECT ,
. errstr = " combined stack " ,
} ,
{
" calls: stack depth check using three frames. test5 " ,
. insns = {
/* main */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call A */
BPF_EXIT_INSN ( ) ,
/* A */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call B */
BPF_EXIT_INSN ( ) ,
/* B */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call C */
BPF_EXIT_INSN ( ) ,
/* C */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call D */
BPF_EXIT_INSN ( ) ,
/* D */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call E */
BPF_EXIT_INSN ( ) ,
/* E */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call F */
BPF_EXIT_INSN ( ) ,
/* F */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call G */
BPF_EXIT_INSN ( ) ,
/* G */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call H */
BPF_EXIT_INSN ( ) ,
/* H */
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " call stack " ,
. result = REJECT ,
} ,
2019-03-20 15:58:50 +03:00
{
" calls: stack depth check in dead code " ,
. insns = {
/* main */
BPF_MOV64_IMM ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call A */
BPF_EXIT_INSN ( ) ,
/* A */
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) , /* call B */
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* B */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call C */
BPF_EXIT_INSN ( ) ,
/* C */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call D */
BPF_EXIT_INSN ( ) ,
/* D */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call E */
BPF_EXIT_INSN ( ) ,
/* E */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call F */
BPF_EXIT_INSN ( ) ,
/* F */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call G */
BPF_EXIT_INSN ( ) ,
/* G */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* call H */
BPF_EXIT_INSN ( ) ,
/* H */
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " call stack " ,
. result = REJECT ,
} ,
2019-01-26 02:24:44 +03:00
{
" calls: spill into caller stack frame " ,
. insns = {
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_1 , BPF_REG_1 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " cannot spill " ,
. result = REJECT ,
} ,
{
" calls: write into caller stack frame " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_6 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_ST_MEM ( BPF_DW , BPF_REG_1 , 0 , 42 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. result = ACCEPT ,
. retval = 42 ,
} ,
{
" calls: write into callee stack frame " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 42 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , - 8 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. errstr = " cannot return stack pointer " ,
. result = REJECT ,
} ,
{
" calls: two calls with stack write and void return " ,
. insns = {
/* main prog */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_10 , - 16 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_7 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* write into stack frame of main prog */
BPF_ST_MEM ( BPF_DW , BPF_REG_1 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) , /* void return */
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. result = ACCEPT ,
} ,
{
" calls: ambiguous return value " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 5 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. errstr_unpriv = " allowed for root only " ,
. result_unpriv = REJECT ,
. errstr = " R0 !read_ok " ,
. result = REJECT ,
} ,
{
" calls: two calls that return map_value " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 8 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_10 , - 8 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 1 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* fetch secound map_value_ptr from the stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_10 , - 16 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 1 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
/* call 3rd function twice */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* first time with fp-8 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_7 ) ,
/* second time with fp-16 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
/* lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr into stack frame of main prog */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) , /* return 0 */
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. fixup_map_hash_8b = { 23 } ,
. result = ACCEPT ,
} ,
{
" calls: two calls that return map_value with bool condition " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
/* call 3rd function twice */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* first time with fp-8 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 9 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_6 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_7 ) ,
/* second time with fp-16 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 1 , 2 ) ,
/* fetch secound map_value_ptr from the stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_7 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
/* lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) , /* return 0 */
/* write map_value_ptr into stack frame of main prog */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) , /* return 1 */
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. fixup_map_hash_8b = { 23 } ,
. result = ACCEPT ,
} ,
{
" calls: two calls that return map_value with incorrect bool check " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
/* call 3rd function twice */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* first time with fp-8 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 9 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_6 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_7 ) ,
/* second time with fp-16 */
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
/* fetch secound map_value_ptr from the stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_7 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
/* lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) , /* return 0 */
/* write map_value_ptr into stack frame of main prog */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 1 ) ,
BPF_EXIT_INSN ( ) , /* return 1 */
} ,
. prog_type = BPF_PROG_TYPE_XDP ,
. fixup_map_hash_8b = { 23 } ,
. result = REJECT ,
. errstr = " invalid read from stack off -16+0 size 8 " ,
} ,
{
" calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1 " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* 1st lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
/* 2nd lookup from map */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) , /* 20 */
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , /* 24 */
BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-16 */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) , /* 30 */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_8 ) ,
BPF_MOV64_REG ( BPF_REG_3 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_9 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* 34 */
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* if arg2 == 1 do *arg1 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_2 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* if arg4 == 1 do *arg3 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_4 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_3 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 2 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 12 , 22 } ,
. result = REJECT ,
. errstr = " invalid access to map value, value_size=8 off=2 size=8 " ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: two calls that receive map_value via arg=ptr_stack_of_caller. test2 " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* 1st lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
/* 2nd lookup from map */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) , /* 20 */
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , /* 24 */
BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-16 */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) , /* 30 */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_8 ) ,
BPF_MOV64_REG ( BPF_REG_3 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_9 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) , /* 34 */
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* if arg2 == 1 do *arg1 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_2 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* if arg4 == 1 do *arg3 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_4 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_3 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 12 , 22 } ,
. result = ACCEPT ,
} ,
{
" calls: two jumps that receive map_value via arg=ptr_stack_of_jumper. test3 " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* 1st lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 24 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 24 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
/* 2nd lookup from map */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 24 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) , // 26
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 2 ) ,
/* write map_value_ptr into stack frame of main prog at fp-16 */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) , // 30
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_8 ) ,
BPF_MOV64_REG ( BPF_REG_3 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_9 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_1 , 0 , 1 ) , // 34
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 30 ) ,
/* subprog 2 */
/* if arg2 == 1 do *arg1 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_2 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* if arg4 == 1 do *arg3 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_4 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_3 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 2 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , - 8 ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 12 , 22 } ,
. result = REJECT ,
. errstr = " invalid access to map value, value_size=8 off=2 size=8 " ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: two calls that receive map_value_ptr_or_null via arg. test1 " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* 1st lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
/* 2nd lookup from map */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_8 ) ,
BPF_MOV64_REG ( BPF_REG_3 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_9 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* if arg2 == 1 do *arg1 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_2 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* if arg4 == 1 do *arg3 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_4 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_3 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 12 , 22 } ,
. result = ACCEPT ,
} ,
{
" calls: two calls that receive map_value_ptr_or_null via arg. test2 " ,
. insns = {
/* main prog */
/* pass fp-16, fp-8 into a function */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_1 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 16 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_MOV64_REG ( BPF_REG_7 , BPF_REG_2 ) ,
/* 1st lookup from map */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
/* 2nd lookup from map */
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr_or_null into stack frame of main prog at fp-16 */
BPF_STX_MEM ( BPF_DW , BPF_REG_7 , BPF_REG_0 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
/* call 3rd func with fp-8, 0|1, fp-16, 0|1 */
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_8 ) ,
BPF_MOV64_REG ( BPF_REG_3 , BPF_REG_7 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_9 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 2 */
/* if arg2 == 1 do *arg1 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_2 , 1 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_1 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
/* if arg4 == 0 do *arg3 = 0 */
BPF_JMP_IMM ( BPF_JNE , BPF_REG_4 , 0 , 2 ) ,
/* fetch map_value_ptr from the stack of this function */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_3 , 0 ) ,
/* write into map value */
BPF_ST_MEM ( BPF_DW , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. fixup_map_hash_8b = { 12 , 22 } ,
. result = REJECT ,
. errstr = " R0 invalid mem access 'inv' " ,
} ,
{
" calls: pkt_ptr spill into caller stack " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 1 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
/* spill unchecked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 2 ) ,
/* now the pkt range is verified, read pkt_ptr from stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_2 , BPF_REG_4 , 0 ) ,
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. result = ACCEPT ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. retval = POINTER_VALUE ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 2 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
/* Marking is still kept, but not in all cases safe. */
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_ST_MEM ( BPF_W , BPF_REG_4 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
/* spill unchecked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 2 ) ,
/* now the pkt range is verified, read pkt_ptr from stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_2 , BPF_REG_4 , 0 ) ,
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " invalid access to packet " ,
. result = REJECT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 3 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 2 ) ,
/* Marking is still kept and safe here. */
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_ST_MEM ( BPF_W , BPF_REG_4 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
/* spill unchecked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 3 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* now the pkt range is verified, read pkt_ptr from stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_2 , BPF_REG_4 , 0 ) ,
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 1 ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 4 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 2 ) ,
/* Check marking propagated. */
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_ST_MEM ( BPF_W , BPF_REG_4 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
/* spill unchecked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. retval = 1 ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 5 " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_4 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 3 ) ,
/* spill checked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " same insn cannot be used with different " ,
. result = REJECT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 6 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_4 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 3 ) ,
/* spill checked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " R4 invalid mem access " ,
. result = REJECT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 7 " ,
. insns = {
BPF_MOV64_IMM ( BPF_REG_2 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_4 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 3 ) ,
/* spill checked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " R4 invalid mem access " ,
. result = REJECT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 8 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_JMP_REG ( BPF_JLE , BPF_REG_0 , BPF_REG_3 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_4 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 3 ) ,
/* spill checked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. result = ACCEPT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: pkt_ptr spill into caller stack 9 " ,
. insns = {
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_JMP_REG ( BPF_JLE , BPF_REG_0 , BPF_REG_3 , 1 ) ,
BPF_EXIT_INSN ( ) ,
BPF_MOV64_REG ( BPF_REG_4 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_4 , - 8 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 3 ) ,
BPF_LDX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_10 , - 8 ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_0 , BPF_REG_4 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
BPF_LDX_MEM ( BPF_W , BPF_REG_2 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data ) ) ,
BPF_LDX_MEM ( BPF_W , BPF_REG_3 , BPF_REG_1 ,
offsetof ( struct __sk_buff , data_end ) ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_2 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_0 , 8 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 0 ) ,
/* spill unchecked pkt_ptr into stack of caller */
BPF_STX_MEM ( BPF_DW , BPF_REG_4 , BPF_REG_2 , 0 ) ,
BPF_JMP_REG ( BPF_JGT , BPF_REG_0 , BPF_REG_3 , 2 ) ,
BPF_MOV64_IMM ( BPF_REG_5 , 1 ) ,
/* don't read back pkt_ptr from stack here */
/* write 4 bytes into packet */
BPF_ST_MEM ( BPF_W , BPF_REG_2 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_0 , BPF_REG_5 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SCHED_CLS ,
. errstr = " invalid access to packet " ,
. result = REJECT ,
. flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS ,
} ,
{
" calls: caller stack init to zero or map_value_or_null " ,
. insns = {
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_STX_MEM ( BPF_DW , BPF_REG_10 , BPF_REG_0 , - 8 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
/* fetch map_value_or_null or const_zero from stack */
BPF_LDX_MEM ( BPF_DW , BPF_REG_0 , BPF_REG_10 , - 8 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_0 , 0 , 1 ) ,
/* store into map_value */
BPF_ST_MEM ( BPF_W , BPF_REG_0 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
/* subprog 1 */
/* if (ctx == 0) return; */
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 8 ) ,
/* else bpf_map_lookup() and *(fp - 8) = r0 */
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_2 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
/* write map_value_ptr_or_null into stack frame of main prog at fp-8 */
BPF_STX_MEM ( BPF_DW , BPF_REG_6 , BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. fixup_map_hash_8b = { 13 } ,
. result = ACCEPT ,
. prog_type = BPF_PROG_TYPE_XDP ,
} ,
{
" calls: stack init to zero and pruning " ,
. insns = {
/* first make allocated_stack 16 byte */
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 16 , 0 ) ,
/* now fork the execution such that the false branch
* of JGT insn will be verified second and it skisp zero
* init of fp - 8 stack slot . If stack liveness marking
* is missing live_read marks from call map_lookup
* processing then pruning will incorrectly assume
* that fp - 8 stack slot was unused in the fall - through
* branch and will accept the program incorrectly
*/
BPF_JMP_IMM ( BPF_JGT , BPF_REG_1 , 2 , 2 ) ,
BPF_ST_MEM ( BPF_DW , BPF_REG_10 , - 8 , 0 ) ,
BPF_JMP_IMM ( BPF_JA , 0 , 0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_2 , BPF_REG_10 ) ,
BPF_ALU64_IMM ( BPF_ADD , BPF_REG_2 , - 8 ) ,
BPF_LD_MAP_FD ( BPF_REG_1 , 0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_map_lookup_elem ) ,
BPF_EXIT_INSN ( ) ,
} ,
. fixup_map_hash_48b = { 6 } ,
. errstr = " invalid indirect read from stack off -8+0 size 8 " ,
. result = REJECT ,
. prog_type = BPF_PROG_TYPE_XDP ,
} ,
{
" calls: ctx read at start of subprog " ,
. insns = {
BPF_MOV64_REG ( BPF_REG_6 , BPF_REG_1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 5 ) ,
BPF_JMP_REG ( BPF_JSGT , BPF_REG_0 , BPF_REG_0 , 0 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_6 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 2 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_9 , BPF_REG_1 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SOCKET_FILTER ,
. errstr_unpriv = " function calls to other bpf functions are allowed for root only " ,
. result_unpriv = REJECT ,
. result = ACCEPT ,
} ,
{
" calls: cross frame pruning " ,
. insns = {
/* r8 = !!random();
* call pruner ( )
* if ( r8 )
* do something bad ;
*/
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_get_prandom_u32 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_8 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_8 , 1 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_9 , BPF_REG_1 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SOCKET_FILTER ,
. errstr_unpriv = " function calls to other bpf functions are allowed for root only " ,
. errstr = " !read_ok " ,
. result = REJECT ,
} ,
2019-03-22 00:34:36 +03:00
{
" calls: cross frame pruning - liveness propagation " ,
. insns = {
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_get_prandom_u32 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_8 , 1 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 0 , 0 , BPF_FUNC_get_prandom_u32 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 0 ) ,
BPF_JMP_IMM ( BPF_JNE , BPF_REG_0 , 0 , 1 ) ,
BPF_MOV64_IMM ( BPF_REG_9 , 1 ) ,
BPF_MOV64_REG ( BPF_REG_1 , BPF_REG_0 ) ,
BPF_RAW_INSN ( BPF_JMP | BPF_CALL , 0 , 1 , 0 , 4 ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_8 , 1 , 1 ) ,
BPF_LDX_MEM ( BPF_B , BPF_REG_1 , BPF_REG_2 , 0 ) ,
BPF_MOV64_IMM ( BPF_REG_0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
BPF_JMP_IMM ( BPF_JEQ , BPF_REG_1 , 0 , 0 ) ,
BPF_EXIT_INSN ( ) ,
} ,
. prog_type = BPF_PROG_TYPE_SOCKET_FILTER ,
. errstr_unpriv = " function calls to other bpf functions are allowed for root only " ,
. errstr = " !read_ok " ,
. result = REJECT ,
} ,