2929#include <linux/filter.h>
3030#include <linux/bpf_perf_event.h>
3131#include <linux/bpf.h>
32+ #include <linux/if_ether.h>
3233
3334#include <bpf/bpf.h>
3435
4950#define MAX_INSNS 512
5051#define MAX_FIXUPS 8
5152#define MAX_NR_MAPS 4
53+ #define POINTER_VALUE 0xcafe4all
54+ #define TEST_DATA_LEN 64
5255
5356#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
5457#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
@@ -62,6 +65,7 @@ struct bpf_test {
6265 int fixup_map_in_map [MAX_FIXUPS ];
6366 const char * errstr ;
6467 const char * errstr_unpriv ;
68+ uint32_t retval ;
6569 enum {
6670 UNDEF ,
6771 ACCEPT ,
@@ -95,6 +99,7 @@ static struct bpf_test tests[] = {
9599 BPF_EXIT_INSN (),
96100 },
97101 .result = ACCEPT ,
102+ .retval = -3 ,
98103 },
99104 {
100105 "unreachable" ,
@@ -210,6 +215,7 @@ static struct bpf_test tests[] = {
210215 BPF_EXIT_INSN (),
211216 },
212217 .result = ACCEPT ,
218+ .retval = 1 ,
213219 },
214220 {
215221 "test8 ld_imm64" ,
@@ -517,6 +523,7 @@ static struct bpf_test tests[] = {
517523 .errstr_unpriv = "R0 leaks addr" ,
518524 .result = ACCEPT ,
519525 .result_unpriv = REJECT ,
526+ .retval = POINTER_VALUE ,
520527 },
521528 {
522529 "check valid spill/fill, skb mark" ,
@@ -803,6 +810,7 @@ static struct bpf_test tests[] = {
803810 .errstr_unpriv = "R1 pointer comparison" ,
804811 .result_unpriv = REJECT ,
805812 .result = ACCEPT ,
813+ .retval = - ENOENT ,
806814 },
807815 {
808816 "jump test 4" ,
@@ -1823,6 +1831,7 @@ static struct bpf_test tests[] = {
18231831 BPF_EXIT_INSN (),
18241832 },
18251833 .result = ACCEPT ,
1834+ .retval = 0xfaceb00c ,
18261835 },
18271836 {
18281837 "PTR_TO_STACK store/load - bad alignment on off" ,
@@ -1881,6 +1890,7 @@ static struct bpf_test tests[] = {
18811890 .result = ACCEPT ,
18821891 .result_unpriv = REJECT ,
18831892 .errstr_unpriv = "R0 leaks addr" ,
1893+ .retval = POINTER_VALUE ,
18841894 },
18851895 {
18861896 "unpriv: add const to pointer" ,
@@ -2054,6 +2064,7 @@ static struct bpf_test tests[] = {
20542064 BPF_LDX_MEM (BPF_DW , BPF_REG_1 , BPF_REG_6 , 0 ),
20552065 BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 ,
20562066 BPF_FUNC_get_hash_recalc ),
2067+ BPF_MOV64_IMM (BPF_REG_0 , 0 ),
20572068 BPF_EXIT_INSN (),
20582069 },
20592070 .result = ACCEPT ,
@@ -2818,6 +2829,7 @@ static struct bpf_test tests[] = {
28182829 },
28192830 .result = ACCEPT ,
28202831 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
2832+ .retval = 1 ,
28212833 },
28222834 {
28232835 "direct packet access: test12 (and, good access)" ,
@@ -2842,6 +2854,7 @@ static struct bpf_test tests[] = {
28422854 },
28432855 .result = ACCEPT ,
28442856 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
2857+ .retval = 1 ,
28452858 },
28462859 {
28472860 "direct packet access: test13 (branches, good access)" ,
@@ -2872,6 +2885,7 @@ static struct bpf_test tests[] = {
28722885 },
28732886 .result = ACCEPT ,
28742887 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
2888+ .retval = 1 ,
28752889 },
28762890 {
28772891 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)" ,
@@ -2895,6 +2909,7 @@ static struct bpf_test tests[] = {
28952909 },
28962910 .result = ACCEPT ,
28972911 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
2912+ .retval = 1 ,
28982913 },
28992914 {
29002915 "direct packet access: test15 (spill with xadd)" ,
@@ -3181,6 +3196,7 @@ static struct bpf_test tests[] = {
31813196 },
31823197 .result = ACCEPT ,
31833198 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
3199+ .retval = 1 ,
31843200 },
31853201 {
31863202 "direct packet access: test28 (marking on <=, bad access)" ,
@@ -5798,6 +5814,7 @@ static struct bpf_test tests[] = {
57985814 },
57995815 .result = ACCEPT ,
58005816 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
5817+ .retval = 0 /* csum_diff of 64-byte packet */ ,
58015818 },
58025819 {
58035820 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)" ,
@@ -6166,6 +6183,7 @@ static struct bpf_test tests[] = {
61666183 },
61676184 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
61686185 .result = ACCEPT ,
6186+ .retval = 42 /* ultimate return value */ ,
61696187 },
61706188 {
61716189 "ld_ind: check calling conv, r1" ,
@@ -6237,6 +6255,7 @@ static struct bpf_test tests[] = {
62376255 BPF_EXIT_INSN (),
62386256 },
62396257 .result = ACCEPT ,
6258+ .retval = 1 ,
62406259 },
62416260 {
62426261 "check bpf_perf_event_data->sample_period byte load permitted" ,
@@ -7224,6 +7243,7 @@ static struct bpf_test tests[] = {
72247243 },
72257244 .fixup_map1 = { 3 },
72267245 .result = ACCEPT ,
7246+ .retval = POINTER_VALUE ,
72277247 .result_unpriv = REJECT ,
72287248 .errstr_unpriv = "R0 leaks addr as return value"
72297249 },
@@ -7244,6 +7264,7 @@ static struct bpf_test tests[] = {
72447264 },
72457265 .fixup_map1 = { 3 },
72467266 .result = ACCEPT ,
7267+ .retval = POINTER_VALUE ,
72477268 .result_unpriv = REJECT ,
72487269 .errstr_unpriv = "R0 leaks addr as return value"
72497270 },
@@ -7685,6 +7706,7 @@ static struct bpf_test tests[] = {
76857706 BPF_EXIT_INSN (),
76867707 },
76877708 .result = ACCEPT ,
7709+ .retval = TEST_DATA_LEN ,
76887710 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
76897711 },
76907712 {
@@ -8705,6 +8727,7 @@ static struct bpf_test tests[] = {
87058727 .errstr_unpriv = "function calls to other bpf functions are allowed for root only" ,
87068728 .result_unpriv = REJECT ,
87078729 .result = ACCEPT ,
8730+ .retval = 1 ,
87088731 },
87098732 {
87108733 "calls: overlapping caller/callee" ,
@@ -8900,6 +8923,7 @@ static struct bpf_test tests[] = {
89008923 },
89018924 .prog_type = BPF_PROG_TYPE_SCHED_ACT ,
89028925 .result = ACCEPT ,
8926+ .retval = TEST_DATA_LEN ,
89038927 },
89048928 {
89058929 "calls: callee using args1" ,
@@ -8912,6 +8936,7 @@ static struct bpf_test tests[] = {
89128936 .errstr_unpriv = "allowed for root only" ,
89138937 .result_unpriv = REJECT ,
89148938 .result = ACCEPT ,
8939+ .retval = POINTER_VALUE ,
89158940 },
89168941 {
89178942 "calls: callee using wrong args2" ,
@@ -8942,6 +8967,7 @@ static struct bpf_test tests[] = {
89428967 .errstr_unpriv = "allowed for root only" ,
89438968 .result_unpriv = REJECT ,
89448969 .result = ACCEPT ,
8970+ .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN ,
89458971 },
89468972 {
89478973 "calls: callee changing pkt pointers" ,
@@ -8990,6 +9016,7 @@ static struct bpf_test tests[] = {
89909016 },
89919017 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
89929018 .result = ACCEPT ,
9019+ .retval = TEST_DATA_LEN + TEST_DATA_LEN ,
89939020 },
89949021 {
89959022 "calls: calls with stack arith" ,
@@ -9008,6 +9035,7 @@ static struct bpf_test tests[] = {
90089035 },
90099036 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
90109037 .result = ACCEPT ,
9038+ .retval = 42 ,
90119039 },
90129040 {
90139041 "calls: calls with misaligned stack access" ,
@@ -9041,6 +9069,7 @@ static struct bpf_test tests[] = {
90419069 },
90429070 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
90439071 .result = ACCEPT ,
9072+ .retval = 43 ,
90449073 },
90459074 {
90469075 "calls: calls control flow, jump test 2" ,
@@ -9533,6 +9562,7 @@ static struct bpf_test tests[] = {
95339562 },
95349563 .prog_type = BPF_PROG_TYPE_XDP ,
95359564 .result = ACCEPT ,
9565+ .retval = 42 ,
95369566 },
95379567 {
95389568 "calls: write into callee stack frame" ,
@@ -10144,6 +10174,7 @@ static struct bpf_test tests[] = {
1014410174 },
1014510175 .result = ACCEPT ,
1014610176 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
10177+ .retval = POINTER_VALUE ,
1014710178 },
1014810179 {
1014910180 "calls: pkt_ptr spill into caller stack 2" ,
@@ -10209,6 +10240,7 @@ static struct bpf_test tests[] = {
1020910240 },
1021010241 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
1021110242 .result = ACCEPT ,
10243+ .retval = 1 ,
1021210244 },
1021310245 {
1021410246 "calls: pkt_ptr spill into caller stack 4" ,
@@ -10242,6 +10274,7 @@ static struct bpf_test tests[] = {
1024210274 },
1024310275 .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
1024410276 .result = ACCEPT ,
10277+ .retval = 1 ,
1024510278 },
1024610279 {
1024710280 "calls: pkt_ptr spill into caller stack 5" ,
@@ -10650,10 +10683,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
1065010683 int fd_prog , expected_ret , reject_from_alignment ;
1065110684 struct bpf_insn * prog = test -> insns ;
1065210685 int prog_len = probe_filter_length (prog );
10686+ char data_in [TEST_DATA_LEN ] = {};
1065310687 int prog_type = test -> prog_type ;
1065410688 int map_fds [MAX_NR_MAPS ];
1065510689 const char * expected_err ;
10656- int i ;
10690+ uint32_t retval ;
10691+ int i , err ;
1065710692
1065810693 for (i = 0 ; i < MAX_NR_MAPS ; i ++ )
1065910694 map_fds [i ] = -1 ;
@@ -10696,6 +10731,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
1069610731 }
1069710732 }
1069810733
10734+ if (fd_prog >= 0 ) {
10735+ err = bpf_prog_test_run (fd_prog , 1 , data_in , sizeof (data_in ),
10736+ NULL , NULL , & retval , NULL );
10737+ if (err && errno != 524 /*ENOTSUPP*/ && errno != EPERM ) {
10738+ printf ("Unexpected bpf_prog_test_run error\n" );
10739+ goto fail_log ;
10740+ }
10741+ if (!err && retval != test -> retval &&
10742+ test -> retval != POINTER_VALUE ) {
10743+ printf ("FAIL retval %d != %d\n" , retval , test -> retval );
10744+ goto fail_log ;
10745+ }
10746+ }
1069910747 (* passes )++ ;
1070010748 printf ("OK%s\n" , reject_from_alignment ?
1070110749 " (NOTE: reject due to unknown alignment)" : "" );
0 commit comments