Skip to content

Commit 6820466

Browse files
kkdwivediNobody
authored and
Nobody
committed
selftests/bpf: Add verifier tests for kptr
Reuse bpf_prog_test functions to test the support for PTR_TO_BTF_ID in BPF map case, including some tests that verify implementation sanity and corner cases. Signed-off-by: Kumar Kartikeya Dwivedi <[email protected]>
1 parent bb39c44 commit 6820466

File tree

3 files changed

+855
-7
lines changed

3 files changed

+855
-7
lines changed

net/bpf/test_run.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,12 @@ noinline void bpf_kfunc_call_memb_release(struct prog_test_member *p)
584584
{
585585
}
586586

587+
noinline struct prog_test_ref_kfunc *
588+
bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b)
589+
{
590+
return &prog_test_struct;
591+
}
592+
587593
struct prog_test_pass1 {
588594
int x0;
589595
struct {
@@ -669,6 +675,7 @@ BTF_ID(func, bpf_kfunc_call_test3)
669675
BTF_ID(func, bpf_kfunc_call_test_acquire)
670676
BTF_ID(func, bpf_kfunc_call_test_release)
671677
BTF_ID(func, bpf_kfunc_call_memb_release)
678+
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
672679
BTF_ID(func, bpf_kfunc_call_test_pass_ctx)
673680
BTF_ID(func, bpf_kfunc_call_test_pass1)
674681
BTF_ID(func, bpf_kfunc_call_test_pass2)
@@ -682,6 +689,7 @@ BTF_SET_END(test_sk_check_kfunc_ids)
682689

683690
BTF_SET_START(test_sk_acquire_kfunc_ids)
684691
BTF_ID(func, bpf_kfunc_call_test_acquire)
692+
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
685693
BTF_SET_END(test_sk_acquire_kfunc_ids)
686694

687695
BTF_SET_START(test_sk_release_kfunc_ids)
@@ -691,8 +699,13 @@ BTF_SET_END(test_sk_release_kfunc_ids)
691699

692700
BTF_SET_START(test_sk_ret_null_kfunc_ids)
693701
BTF_ID(func, bpf_kfunc_call_test_acquire)
702+
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
694703
BTF_SET_END(test_sk_ret_null_kfunc_ids)
695704

705+
BTF_SET_START(test_sk_kptr_acquire_kfunc_ids)
706+
BTF_ID(func, bpf_kfunc_call_test_kptr_get)
707+
BTF_SET_END(test_sk_kptr_acquire_kfunc_ids)
708+
696709
static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
697710
u32 size, u32 headroom, u32 tailroom)
698711
{
@@ -1579,14 +1592,30 @@ int bpf_prog_test_run_syscall(struct bpf_prog *prog,
15791592

15801593
static const struct btf_kfunc_id_set bpf_prog_test_kfunc_set = {
15811594
.owner = THIS_MODULE,
1582-
.check_set = &test_sk_check_kfunc_ids,
1583-
.acquire_set = &test_sk_acquire_kfunc_ids,
1584-
.release_set = &test_sk_release_kfunc_ids,
1585-
.ret_null_set = &test_sk_ret_null_kfunc_ids,
1595+
.check_set = &test_sk_check_kfunc_ids,
1596+
.acquire_set = &test_sk_acquire_kfunc_ids,
1597+
.release_set = &test_sk_release_kfunc_ids,
1598+
.ret_null_set = &test_sk_ret_null_kfunc_ids,
1599+
.kptr_acquire_set = &test_sk_kptr_acquire_kfunc_ids
15861600
};
15871601

1602+
BTF_ID_LIST(bpf_prog_test_dtor_kfunc_ids)
1603+
BTF_ID(struct, prog_test_ref_kfunc)
1604+
BTF_ID(func, bpf_kfunc_call_test_release)
1605+
15881606
static int __init bpf_prog_test_run_init(void)
15891607
{
1590-
return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_prog_test_kfunc_set);
1608+
const struct btf_id_dtor_kfunc bpf_prog_test_dtor_kfunc[] = {
1609+
{
1610+
.btf_id = bpf_prog_test_dtor_kfunc_ids[0],
1611+
.kfunc_btf_id = bpf_prog_test_dtor_kfunc_ids[1]
1612+
},
1613+
};
1614+
int ret;
1615+
1616+
ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_prog_test_kfunc_set);
1617+
return ret ?: register_btf_id_dtor_kfuncs(bpf_prog_test_dtor_kfunc,
1618+
ARRAY_SIZE(bpf_prog_test_dtor_kfunc),
1619+
THIS_MODULE);
15911620
}
15921621
late_initcall(bpf_prog_test_run_init);

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#define MAX_INSNS BPF_MAXINSNS
5454
#define MAX_TEST_INSNS 1000000
5555
#define MAX_FIXUPS 8
56-
#define MAX_NR_MAPS 22
56+
#define MAX_NR_MAPS 23
5757
#define MAX_TEST_RUNS 8
5858
#define POINTER_VALUE 0xcafe4all
5959
#define TEST_DATA_LEN 64
@@ -101,6 +101,7 @@ struct bpf_test {
101101
int fixup_map_reuseport_array[MAX_FIXUPS];
102102
int fixup_map_ringbuf[MAX_FIXUPS];
103103
int fixup_map_timer[MAX_FIXUPS];
104+
int fixup_map_kptr[MAX_FIXUPS];
104105
struct kfunc_btf_id_pair fixup_kfunc_btf_id[MAX_FIXUPS];
105106
/* Expected verifier log output for result REJECT or VERBOSE_ACCEPT.
106107
* Can be a tab-separated sequence of expected strings. An empty string
@@ -621,8 +622,16 @@ static int create_cgroup_storage(bool percpu)
621622
* struct timer {
622623
* struct bpf_timer t;
623624
* };
625+
* struct btf_ptr {
626+
* struct prog_test_ref_kfunc __kptr *ptr;
627+
* struct prog_test_ref_kfunc __kptr_ref *ptr;
628+
* struct prog_test_ref_kfunc __kptr_percpu *ptr;
629+
* struct prog_test_ref_kfunc __kptr_user *ptr;
630+
* }
624631
*/
625-
static const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l\0bpf_timer\0timer\0t";
632+
static const char btf_str_sec[] = "\0bpf_spin_lock\0val\0cnt\0l\0bpf_timer\0timer\0t"
633+
"\0btf_ptr\0prog_test_ref_kfunc\0ptr\0kptr\0kptr_ref"
634+
"\0kptr_percpu\0kptr_user";
626635
static __u32 btf_raw_types[] = {
627636
/* int */
628637
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
@@ -638,6 +647,26 @@ static __u32 btf_raw_types[] = {
638647
/* struct timer */ /* [5] */
639648
BTF_TYPE_ENC(35, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),
640649
BTF_MEMBER_ENC(41, 4, 0), /* struct bpf_timer t; */
650+
/* struct prog_test_ref_kfunc */ /* [6] */
651+
BTF_STRUCT_ENC(51, 0, 0),
652+
/* type tag "kptr" */
653+
BTF_TYPE_TAG_ENC(75, 6), /* [7] */
654+
/* type tag "kptr_ref" */
655+
BTF_TYPE_TAG_ENC(80, 6), /* [8] */
656+
/* type tag "kptr_percpu" */
657+
BTF_TYPE_TAG_ENC(89, 6), /* [9] */
658+
/* type tag "kptr_user" */
659+
BTF_TYPE_TAG_ENC(101, 6), /* [10] */
660+
BTF_PTR_ENC(7), /* [11] */
661+
BTF_PTR_ENC(8), /* [12] */
662+
BTF_PTR_ENC(9), /* [13] */
663+
BTF_PTR_ENC(10), /* [14] */
664+
/* struct btf_ptr */ /* [15] */
665+
BTF_STRUCT_ENC(43, 4, 32),
666+
BTF_MEMBER_ENC(71, 11, 0), /* struct prog_test_ref_kfunc __kptr *ptr; */
667+
BTF_MEMBER_ENC(71, 12, 64), /* struct prog_test_ref_kfunc __kptr_ref *ptr; */
668+
BTF_MEMBER_ENC(71, 13, 128), /* struct prog_test_ref_kfunc __kptr_percpu *ptr; */
669+
BTF_MEMBER_ENC(71, 14, 192), /* struct prog_test_ref_kfunc __kptr_user *ptr; */
641670
};
642671

643672
static int load_btf(void)
@@ -727,6 +756,25 @@ static int create_map_timer(void)
727756
return fd;
728757
}
729758

759+
static int create_map_kptr(void)
760+
{
761+
LIBBPF_OPTS(bpf_map_create_opts, opts,
762+
.btf_key_type_id = 1,
763+
.btf_value_type_id = 15,
764+
);
765+
int fd, btf_fd;
766+
767+
btf_fd = load_btf();
768+
if (btf_fd < 0)
769+
return -1;
770+
771+
opts.btf_fd = btf_fd;
772+
fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_map", 4, 32, 1, &opts);
773+
if (fd < 0)
774+
printf("Failed to create map with btf_id pointer\n");
775+
return fd;
776+
}
777+
730778
static char bpf_vlog[UINT_MAX >> 8];
731779

732780
static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
@@ -754,6 +802,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
754802
int *fixup_map_reuseport_array = test->fixup_map_reuseport_array;
755803
int *fixup_map_ringbuf = test->fixup_map_ringbuf;
756804
int *fixup_map_timer = test->fixup_map_timer;
805+
int *fixup_map_kptr = test->fixup_map_kptr;
757806
struct kfunc_btf_id_pair *fixup_kfunc_btf_id = test->fixup_kfunc_btf_id;
758807

759808
if (test->fill_helper) {
@@ -947,6 +996,13 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
947996
fixup_map_timer++;
948997
} while (*fixup_map_timer);
949998
}
999+
if (*fixup_map_kptr) {
1000+
map_fds[22] = create_map_kptr();
1001+
do {
1002+
prog[*fixup_map_kptr].imm = map_fds[22];
1003+
fixup_map_kptr++;
1004+
} while (*fixup_map_kptr);
1005+
}
9501006

9511007
/* Patch in kfunc BTF IDs */
9521008
if (fixup_kfunc_btf_id->kfunc) {

0 commit comments

Comments
 (0)