50
50
51
51
#define MAX_INSNS BPF_MAXINSNS
52
52
#define MAX_FIXUPS 8
53
- #define MAX_NR_MAPS 4
53
+ #define MAX_NR_MAPS 7
54
54
#define POINTER_VALUE 0xcafe4all
55
55
#define TEST_DATA_LEN 64
56
56
@@ -66,7 +66,9 @@ struct bpf_test {
66
66
int fixup_map1 [MAX_FIXUPS ];
67
67
int fixup_map2 [MAX_FIXUPS ];
68
68
int fixup_map3 [MAX_FIXUPS ];
69
- int fixup_prog [MAX_FIXUPS ];
69
+ int fixup_map4 [MAX_FIXUPS ];
70
+ int fixup_prog1 [MAX_FIXUPS ];
71
+ int fixup_prog2 [MAX_FIXUPS ];
70
72
int fixup_map_in_map [MAX_FIXUPS ];
71
73
const char * errstr ;
72
74
const char * errstr_unpriv ;
@@ -2769,7 +2771,7 @@ static struct bpf_test tests[] = {
2769
2771
BPF_MOV64_IMM (BPF_REG_0 , 0 ),
2770
2772
BPF_EXIT_INSN (),
2771
2773
},
2772
- .fixup_prog = { 1 },
2774
+ .fixup_prog1 = { 1 },
2773
2775
.errstr_unpriv = "R3 leaks addr into helper" ,
2774
2776
.result_unpriv = REJECT ,
2775
2777
.result = ACCEPT ,
@@ -2856,7 +2858,7 @@ static struct bpf_test tests[] = {
2856
2858
BPF_MOV64_IMM (BPF_REG_0 , 1 ),
2857
2859
BPF_EXIT_INSN (),
2858
2860
},
2859
- .fixup_prog = { 1 },
2861
+ .fixup_prog1 = { 1 },
2860
2862
.result = ACCEPT ,
2861
2863
.retval = 42 ,
2862
2864
},
@@ -2870,7 +2872,7 @@ static struct bpf_test tests[] = {
2870
2872
BPF_MOV64_IMM (BPF_REG_0 , 1 ),
2871
2873
BPF_EXIT_INSN (),
2872
2874
},
2873
- .fixup_prog = { 1 },
2875
+ .fixup_prog1 = { 1 },
2874
2876
.result = ACCEPT ,
2875
2877
.retval = 41 ,
2876
2878
},
@@ -2884,7 +2886,7 @@ static struct bpf_test tests[] = {
2884
2886
BPF_MOV64_IMM (BPF_REG_0 , 1 ),
2885
2887
BPF_EXIT_INSN (),
2886
2888
},
2887
- .fixup_prog = { 1 },
2889
+ .fixup_prog1 = { 1 },
2888
2890
.result = ACCEPT ,
2889
2891
.retval = 1 ,
2890
2892
},
@@ -2898,7 +2900,7 @@ static struct bpf_test tests[] = {
2898
2900
BPF_MOV64_IMM (BPF_REG_0 , 2 ),
2899
2901
BPF_EXIT_INSN (),
2900
2902
},
2901
- .fixup_prog = { 1 },
2903
+ .fixup_prog1 = { 1 },
2902
2904
.result = ACCEPT ,
2903
2905
.retval = 2 ,
2904
2906
},
@@ -2912,7 +2914,7 @@ static struct bpf_test tests[] = {
2912
2914
BPF_MOV64_IMM (BPF_REG_0 , 2 ),
2913
2915
BPF_EXIT_INSN (),
2914
2916
},
2915
- .fixup_prog = { 1 },
2917
+ .fixup_prog1 = { 1 },
2916
2918
.result = ACCEPT ,
2917
2919
.retval = 2 ,
2918
2920
},
@@ -2926,7 +2928,7 @@ static struct bpf_test tests[] = {
2926
2928
BPF_MOV64_IMM (BPF_REG_0 , 2 ),
2927
2929
BPF_EXIT_INSN (),
2928
2930
},
2929
- .fixup_prog = { 2 },
2931
+ .fixup_prog1 = { 2 },
2930
2932
.result = ACCEPT ,
2931
2933
.retval = 42 ,
2932
2934
},
@@ -11681,6 +11683,112 @@ static struct bpf_test tests[] = {
11681
11683
.result = REJECT ,
11682
11684
.prog_type = BPF_PROG_TYPE_XDP ,
11683
11685
},
11686
+ {
11687
+ "calls: two calls returning different map pointers for lookup (hash, array)" ,
11688
+ .insns = {
11689
+ /* main prog */
11690
+ BPF_JMP_IMM (BPF_JNE , BPF_REG_1 , 0 , 2 ),
11691
+ BPF_CALL_REL (11 ),
11692
+ BPF_JMP_IMM (BPF_JA , 0 , 0 , 1 ),
11693
+ BPF_CALL_REL (12 ),
11694
+ BPF_MOV64_REG (BPF_REG_1 , BPF_REG_0 ),
11695
+ BPF_ST_MEM (BPF_DW , BPF_REG_10 , -8 , 0 ),
11696
+ BPF_MOV64_REG (BPF_REG_2 , BPF_REG_10 ),
11697
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_2 , -8 ),
11698
+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 ,
11699
+ BPF_FUNC_map_lookup_elem ),
11700
+ BPF_JMP_IMM (BPF_JEQ , BPF_REG_0 , 0 , 2 ),
11701
+ BPF_ST_MEM (BPF_DW , BPF_REG_0 , 0 ,
11702
+ offsetof(struct test_val , foo )),
11703
+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
11704
+ BPF_EXIT_INSN (),
11705
+ /* subprog 1 */
11706
+ BPF_LD_MAP_FD (BPF_REG_0 , 0 ),
11707
+ BPF_EXIT_INSN (),
11708
+ /* subprog 2 */
11709
+ BPF_LD_MAP_FD (BPF_REG_0 , 0 ),
11710
+ BPF_EXIT_INSN (),
11711
+ },
11712
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
11713
+ .fixup_map2 = { 13 },
11714
+ .fixup_map4 = { 16 },
11715
+ .result = ACCEPT ,
11716
+ .retval = 1 ,
11717
+ },
11718
+ {
11719
+ "calls: two calls returning different map pointers for lookup (hash, map in map)" ,
11720
+ .insns = {
11721
+ /* main prog */
11722
+ BPF_JMP_IMM (BPF_JNE , BPF_REG_1 , 0 , 2 ),
11723
+ BPF_CALL_REL (11 ),
11724
+ BPF_JMP_IMM (BPF_JA , 0 , 0 , 1 ),
11725
+ BPF_CALL_REL (12 ),
11726
+ BPF_MOV64_REG (BPF_REG_1 , BPF_REG_0 ),
11727
+ BPF_ST_MEM (BPF_DW , BPF_REG_10 , -8 , 0 ),
11728
+ BPF_MOV64_REG (BPF_REG_2 , BPF_REG_10 ),
11729
+ BPF_ALU64_IMM (BPF_ADD , BPF_REG_2 , -8 ),
11730
+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 ,
11731
+ BPF_FUNC_map_lookup_elem ),
11732
+ BPF_JMP_IMM (BPF_JEQ , BPF_REG_0 , 0 , 2 ),
11733
+ BPF_ST_MEM (BPF_DW , BPF_REG_0 , 0 ,
11734
+ offsetof(struct test_val , foo )),
11735
+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
11736
+ BPF_EXIT_INSN (),
11737
+ /* subprog 1 */
11738
+ BPF_LD_MAP_FD (BPF_REG_0 , 0 ),
11739
+ BPF_EXIT_INSN (),
11740
+ /* subprog 2 */
11741
+ BPF_LD_MAP_FD (BPF_REG_0 , 0 ),
11742
+ BPF_EXIT_INSN (),
11743
+ },
11744
+ .prog_type = BPF_PROG_TYPE_SCHED_CLS ,
11745
+ .fixup_map_in_map = { 16 },
11746
+ .fixup_map4 = { 13 },
11747
+ .result = REJECT ,
11748
+ .errstr = "R0 invalid mem access 'map_ptr'" ,
11749
+ },
11750
+ {
11751
+ "cond: two branches returning different map pointers for lookup (tail, tail)" ,
11752
+ .insns = {
11753
+ BPF_LDX_MEM (BPF_W , BPF_REG_6 , BPF_REG_1 ,
11754
+ offsetof(struct __sk_buff , mark )),
11755
+ BPF_JMP_IMM (BPF_JNE , BPF_REG_6 , 0 , 3 ),
11756
+ BPF_LD_MAP_FD (BPF_REG_2 , 0 ),
11757
+ BPF_JMP_IMM (BPF_JA , 0 , 0 , 2 ),
11758
+ BPF_LD_MAP_FD (BPF_REG_2 , 0 ),
11759
+ BPF_MOV64_IMM (BPF_REG_3 , 7 ),
11760
+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 ,
11761
+ BPF_FUNC_tail_call ),
11762
+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
11763
+ BPF_EXIT_INSN (),
11764
+ },
11765
+ .fixup_prog1 = { 5 },
11766
+ .fixup_prog2 = { 2 },
11767
+ .result_unpriv = REJECT ,
11768
+ .errstr_unpriv = "tail_call abusing map_ptr" ,
11769
+ .result = ACCEPT ,
11770
+ .retval = 42 ,
11771
+ },
11772
+ {
11773
+ "cond: two branches returning same map pointers for lookup (tail, tail)" ,
11774
+ .insns = {
11775
+ BPF_LDX_MEM (BPF_W , BPF_REG_6 , BPF_REG_1 ,
11776
+ offsetof(struct __sk_buff , mark )),
11777
+ BPF_JMP_IMM (BPF_JEQ , BPF_REG_6 , 0 , 3 ),
11778
+ BPF_LD_MAP_FD (BPF_REG_2 , 0 ),
11779
+ BPF_JMP_IMM (BPF_JA , 0 , 0 , 2 ),
11780
+ BPF_LD_MAP_FD (BPF_REG_2 , 0 ),
11781
+ BPF_MOV64_IMM (BPF_REG_3 , 7 ),
11782
+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , 0 , 0 ,
11783
+ BPF_FUNC_tail_call ),
11784
+ BPF_MOV64_IMM (BPF_REG_0 , 1 ),
11785
+ BPF_EXIT_INSN (),
11786
+ },
11787
+ .fixup_prog2 = { 2 , 5 },
11788
+ .result_unpriv = ACCEPT ,
11789
+ .result = ACCEPT ,
11790
+ .retval = 42 ,
11791
+ },
11684
11792
{
11685
11793
"search pruning: all branches should be verified (nop operation)" ,
11686
11794
.insns = {
@@ -12162,12 +12270,13 @@ static int probe_filter_length(const struct bpf_insn *fp)
12162
12270
return len + 1 ;
12163
12271
}
12164
12272
12165
- static int create_map (uint32_t size_value , uint32_t max_elem )
12273
+ static int create_map (uint32_t type , uint32_t size_key ,
12274
+ uint32_t size_value , uint32_t max_elem )
12166
12275
{
12167
12276
int fd ;
12168
12277
12169
- fd = bpf_create_map (BPF_MAP_TYPE_HASH , sizeof ( long long ) ,
12170
- size_value , max_elem , BPF_F_NO_PREALLOC );
12278
+ fd = bpf_create_map (type , size_key , size_value , max_elem ,
12279
+ type == BPF_MAP_TYPE_HASH ? BPF_F_NO_PREALLOC : 0 );
12171
12280
if (fd < 0 )
12172
12281
printf ("Failed to create hash map '%s'!\n" , strerror (errno ));
12173
12282
@@ -12200,13 +12309,13 @@ static int create_prog_dummy2(int mfd, int idx)
12200
12309
ARRAY_SIZE (prog ), "GPL" , 0 , NULL , 0 );
12201
12310
}
12202
12311
12203
- static int create_prog_array (void )
12312
+ static int create_prog_array (uint32_t max_elem , int p1key )
12204
12313
{
12205
- int p1key = 0 , p2key = 1 ;
12314
+ int p2key = 1 ;
12206
12315
int mfd , p1fd , p2fd ;
12207
12316
12208
12317
mfd = bpf_create_map (BPF_MAP_TYPE_PROG_ARRAY , sizeof (int ),
12209
- sizeof (int ), 4 , 0 );
12318
+ sizeof (int ), max_elem , 0 );
12210
12319
if (mfd < 0 ) {
12211
12320
printf ("Failed to create prog array '%s'!\n" , strerror (errno ));
12212
12321
return -1 ;
@@ -12261,7 +12370,9 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12261
12370
int * fixup_map1 = test -> fixup_map1 ;
12262
12371
int * fixup_map2 = test -> fixup_map2 ;
12263
12372
int * fixup_map3 = test -> fixup_map3 ;
12264
- int * fixup_prog = test -> fixup_prog ;
12373
+ int * fixup_map4 = test -> fixup_map4 ;
12374
+ int * fixup_prog1 = test -> fixup_prog1 ;
12375
+ int * fixup_prog2 = test -> fixup_prog2 ;
12265
12376
int * fixup_map_in_map = test -> fixup_map_in_map ;
12266
12377
12267
12378
if (test -> fill_helper )
@@ -12272,41 +12383,61 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
12272
12383
* that really matters is value size in this case.
12273
12384
*/
12274
12385
if (* fixup_map1 ) {
12275
- map_fds [0 ] = create_map (sizeof (long long ), 1 );
12386
+ map_fds [0 ] = create_map (BPF_MAP_TYPE_HASH , sizeof (long long ),
12387
+ sizeof (long long ), 1 );
12276
12388
do {
12277
12389
prog [* fixup_map1 ].imm = map_fds [0 ];
12278
12390
fixup_map1 ++ ;
12279
12391
} while (* fixup_map1 );
12280
12392
}
12281
12393
12282
12394
if (* fixup_map2 ) {
12283
- map_fds [1 ] = create_map (sizeof (struct test_val ), 1 );
12395
+ map_fds [1 ] = create_map (BPF_MAP_TYPE_HASH , sizeof (long long ),
12396
+ sizeof (struct test_val ), 1 );
12284
12397
do {
12285
12398
prog [* fixup_map2 ].imm = map_fds [1 ];
12286
12399
fixup_map2 ++ ;
12287
12400
} while (* fixup_map2 );
12288
12401
}
12289
12402
12290
12403
if (* fixup_map3 ) {
12291
- map_fds [1 ] = create_map (sizeof (struct other_val ), 1 );
12404
+ map_fds [2 ] = create_map (BPF_MAP_TYPE_HASH , sizeof (long long ),
12405
+ sizeof (struct other_val ), 1 );
12292
12406
do {
12293
- prog [* fixup_map3 ].imm = map_fds [1 ];
12407
+ prog [* fixup_map3 ].imm = map_fds [2 ];
12294
12408
fixup_map3 ++ ;
12295
12409
} while (* fixup_map3 );
12296
12410
}
12297
12411
12298
- if (* fixup_prog ) {
12299
- map_fds [2 ] = create_prog_array ();
12412
+ if (* fixup_map4 ) {
12413
+ map_fds [3 ] = create_map (BPF_MAP_TYPE_ARRAY , sizeof (int ),
12414
+ sizeof (struct test_val ), 1 );
12415
+ do {
12416
+ prog [* fixup_map4 ].imm = map_fds [3 ];
12417
+ fixup_map4 ++ ;
12418
+ } while (* fixup_map4 );
12419
+ }
12420
+
12421
+ if (* fixup_prog1 ) {
12422
+ map_fds [4 ] = create_prog_array (4 , 0 );
12423
+ do {
12424
+ prog [* fixup_prog1 ].imm = map_fds [4 ];
12425
+ fixup_prog1 ++ ;
12426
+ } while (* fixup_prog1 );
12427
+ }
12428
+
12429
+ if (* fixup_prog2 ) {
12430
+ map_fds [5 ] = create_prog_array (8 , 7 );
12300
12431
do {
12301
- prog [* fixup_prog ].imm = map_fds [2 ];
12302
- fixup_prog ++ ;
12303
- } while (* fixup_prog );
12432
+ prog [* fixup_prog2 ].imm = map_fds [5 ];
12433
+ fixup_prog2 ++ ;
12434
+ } while (* fixup_prog2 );
12304
12435
}
12305
12436
12306
12437
if (* fixup_map_in_map ) {
12307
- map_fds [3 ] = create_map_in_map ();
12438
+ map_fds [6 ] = create_map_in_map ();
12308
12439
do {
12309
- prog [* fixup_map_in_map ].imm = map_fds [3 ];
12440
+ prog [* fixup_map_in_map ].imm = map_fds [6 ];
12310
12441
fixup_map_in_map ++ ;
12311
12442
} while (* fixup_map_in_map );
12312
12443
}
0 commit comments