Message ID | 20220806074019.2756957-9-houtao@huaweicloud.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | fixes for bpf map iterator | expand |
On 8/6/22 12:40 AM, Hou Tao wrote: > From: Hou Tao <houtao1@huawei.com> > > Add test to validate the overwrite of sock storage map value in map > iterator and another one to ensure out-of-bound value writing is > rejected. > > Signed-off-by: Hou Tao <houtao1@huawei.com> One nit below. Acked-by: Yonghong Song <yhs@fb.com> > --- > .../selftests/bpf/prog_tests/bpf_iter.c | 20 +++++++++++++++++-- > .../bpf/progs/bpf_iter_bpf_sk_storage_map.c | 20 ++++++++++++++++++- > 2 files changed, 37 insertions(+), 3 deletions(-) > > diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > index 94c2c8df3fe4..f75308d75570 100644 > --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > @@ -1074,7 +1074,7 @@ static void test_bpf_sk_stoarge_map_iter_fd(void) > if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_sk_storage_map__open_and_load")) > return; > > - do_read_map_iter_fd(&skel->skeleton, skel->progs.dump_bpf_sk_storage_map, > + do_read_map_iter_fd(&skel->skeleton, skel->progs.rw_bpf_sk_storage_map, > skel->maps.sk_stg_map); > > bpf_iter_bpf_sk_storage_map__destroy(skel); > @@ -1115,7 +1115,15 @@ static void test_bpf_sk_storage_map(void) > linfo.map.map_fd = map_fd; > opts.link_info = &linfo; > opts.link_info_len = sizeof(linfo); > - link = bpf_program__attach_iter(skel->progs.dump_bpf_sk_storage_map, &opts); > + link = bpf_program__attach_iter(skel->progs.oob_write_bpf_sk_storage_map, &opts); > + err = libbpf_get_error(link); > + if (!ASSERT_EQ(err, -EACCES, "attach_oob_write_iter")) { > + if (!err) > + bpf_link__destroy(link); > + goto out; > + } > + > + link = bpf_program__attach_iter(skel->progs.rw_bpf_sk_storage_map, &opts); > if (!ASSERT_OK_PTR(link, "attach_iter")) > goto out; > > @@ -1123,6 +1131,7 @@ static void test_bpf_sk_storage_map(void) > if (!ASSERT_GE(iter_fd, 0, "create_iter")) > goto free_link; > > + skel->bss->to_add_val = time(NULL); > /* do some tests */ > while ((len = read(iter_fd, buf, sizeof(buf))) > 0) > ; > @@ -1136,6 +1145,13 @@ static void test_bpf_sk_storage_map(void) > if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum")) > goto close_iter; > > + for (i = 0; i < num_sockets; i++) { > + err = bpf_map_lookup_elem(map_fd, &sock_fd[i], &val); > + if (!ASSERT_OK(err, "map_lookup") || > + !ASSERT_EQ(val, i + 1 + skel->bss->to_add_val, "check_map_value")) > + break; > + } > + > close_iter: > close(iter_fd); > free_link: > diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c > index 6b70ccaba301..6a82f8b0c0fa 100644 > --- a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c > +++ b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c > @@ -16,9 +16,10 @@ struct { > > __u32 val_sum = 0; > __u32 ipv6_sk_count = 0; > +__u32 to_add_val = 0; > > SEC("iter/bpf_sk_storage_map") > -int dump_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) > +int rw_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) > { > struct sock *sk = ctx->sk; > __u32 *val = ctx->value; > @@ -30,5 +31,22 @@ int dump_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) > ipv6_sk_count++; > > val_sum += *val; > + > + *val += to_add_val; > + > + return 0; > +} > + > +SEC("iter/bpf_sk_storage_map") > +int oob_write_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) > +{ > + struct sock *sk = ctx->sk; > + __u32 *val = ctx->value; > + > + if (sk == (void *)0 || val == (void *)0) Newer bpf_helpers.h provides NULL for (void *)0, you can use NULL now. > + return 0; > + > + *(val + 1) = 0xdeadbeef; > + > return 0; > }
Hi, On 8/8/2022 11:27 PM, Yonghong Song wrote: > > > On 8/6/22 12:40 AM, Hou Tao wrote: >> From: Hou Tao <houtao1@huawei.com> >> >> Add test to validate the overwrite of sock storage map value in map >> iterator and another one to ensure out-of-bound value writing is >> rejected. >> >> Signed-off-by: Hou Tao <houtao1@huawei.com> > > One nit below. > > Acked-by: Yonghong Song <yhs@fb.com> > >> --- >> .../selftests/bpf/prog_tests/bpf_iter.c | 20 +++++++++++++++++-- >> .../bpf/progs/bpf_iter_bpf_sk_storage_map.c | 20 ++++++++++++++++++- >> 2 files changed, 37 insertions(+), 3 deletions(-) >> SNIP >> SEC("iter/bpf_sk_storage_map") >> -int dump_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) >> +int rw_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) >> { >> struct sock *sk = ctx->sk; >> __u32 *val = ctx->value; >> @@ -30,5 +31,22 @@ int dump_bpf_sk_storage_map(struct >> bpf_iter__bpf_sk_storage_map *ctx) >> ipv6_sk_count++; >> val_sum += *val; >> + >> + *val += to_add_val; >> + >> + return 0; >> +} >> + >> +SEC("iter/bpf_sk_storage_map") >> +int oob_write_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) >> +{ >> + struct sock *sk = ctx->sk; >> + __u32 *val = ctx->value; >> + >> + if (sk == (void *)0 || val == (void *)0) > > Newer bpf_helpers.h provides NULL for (void *)0, you can use NULL now. Thanks. Will fix in v2. > >> + return 0; >> + >> + *(val + 1) = 0xdeadbeef; >> + >> return 0; >> }
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c index 94c2c8df3fe4..f75308d75570 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c @@ -1074,7 +1074,7 @@ static void test_bpf_sk_stoarge_map_iter_fd(void) if (!ASSERT_OK_PTR(skel, "bpf_iter_bpf_sk_storage_map__open_and_load")) return; - do_read_map_iter_fd(&skel->skeleton, skel->progs.dump_bpf_sk_storage_map, + do_read_map_iter_fd(&skel->skeleton, skel->progs.rw_bpf_sk_storage_map, skel->maps.sk_stg_map); bpf_iter_bpf_sk_storage_map__destroy(skel); @@ -1115,7 +1115,15 @@ static void test_bpf_sk_storage_map(void) linfo.map.map_fd = map_fd; opts.link_info = &linfo; opts.link_info_len = sizeof(linfo); - link = bpf_program__attach_iter(skel->progs.dump_bpf_sk_storage_map, &opts); + link = bpf_program__attach_iter(skel->progs.oob_write_bpf_sk_storage_map, &opts); + err = libbpf_get_error(link); + if (!ASSERT_EQ(err, -EACCES, "attach_oob_write_iter")) { + if (!err) + bpf_link__destroy(link); + goto out; + } + + link = bpf_program__attach_iter(skel->progs.rw_bpf_sk_storage_map, &opts); if (!ASSERT_OK_PTR(link, "attach_iter")) goto out; @@ -1123,6 +1131,7 @@ static void test_bpf_sk_storage_map(void) if (!ASSERT_GE(iter_fd, 0, "create_iter")) goto free_link; + skel->bss->to_add_val = time(NULL); /* do some tests */ while ((len = read(iter_fd, buf, sizeof(buf))) > 0) ; @@ -1136,6 +1145,13 @@ static void test_bpf_sk_storage_map(void) if (!ASSERT_EQ(skel->bss->val_sum, expected_val, "val_sum")) goto close_iter; + for (i = 0; i < num_sockets; i++) { + err = bpf_map_lookup_elem(map_fd, &sock_fd[i], &val); + if (!ASSERT_OK(err, "map_lookup") || + !ASSERT_EQ(val, i + 1 + skel->bss->to_add_val, "check_map_value")) + break; + } + close_iter: close(iter_fd); free_link: diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c index 6b70ccaba301..6a82f8b0c0fa 100644 --- a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c +++ b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_sk_storage_map.c @@ -16,9 +16,10 @@ struct { __u32 val_sum = 0; __u32 ipv6_sk_count = 0; +__u32 to_add_val = 0; SEC("iter/bpf_sk_storage_map") -int dump_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) +int rw_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) { struct sock *sk = ctx->sk; __u32 *val = ctx->value; @@ -30,5 +31,22 @@ int dump_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) ipv6_sk_count++; val_sum += *val; + + *val += to_add_val; + + return 0; +} + +SEC("iter/bpf_sk_storage_map") +int oob_write_bpf_sk_storage_map(struct bpf_iter__bpf_sk_storage_map *ctx) +{ + struct sock *sk = ctx->sk; + __u32 *val = ctx->value; + + if (sk == (void *)0 || val == (void *)0) + return 0; + + *(val + 1) = 0xdeadbeef; + return 0; }