eBPF selftests produce a few false positives with MSan. These can be divided in two classes: - Sending uninitalized data via a socket. - bpf_obj_get_info_by_fd() calls. The first class is trivial; the second should ideally be handled by libbpf, but it doesn't look possible at the moment, since we don't know the type of the eBPF object referred to by fd, and therefore the structure of the output data. Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> --- tools/testing/selftests/bpf/cap_helpers.c | 3 +++ tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c | 10 ++++++++++ tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c | 3 +++ tools/testing/selftests/bpf/prog_tests/btf.c | 11 +++++++++++ tools/testing/selftests/bpf/prog_tests/send_signal.c | 2 ++ .../selftests/bpf/prog_tests/tp_attach_query.c | 6 ++++++ tools/testing/selftests/bpf/prog_tests/xdp_bonding.c | 3 +++ tools/testing/selftests/bpf/xdp_synproxy.c | 2 ++ 8 files changed, 40 insertions(+) diff --git a/tools/testing/selftests/bpf/cap_helpers.c b/tools/testing/selftests/bpf/cap_helpers.c index d5ac507401d7..f5775b342b30 100644 --- a/tools/testing/selftests/bpf/cap_helpers.c +++ b/tools/testing/selftests/bpf/cap_helpers.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include <bpf/libbpf_internal.h> #include "cap_helpers.h" /* Avoid including <sys/capability.h> from the libcap-devel package, @@ -20,6 +21,7 @@ int cap_enable_effective(__u64 caps, __u64 *old_caps) err = capget(&hdr, data); if (err) return err; + libbpf_mark_defined(data, sizeof(data)); if (old_caps) *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; @@ -50,6 +52,7 @@ int cap_disable_effective(__u64 caps, __u64 *old_caps) err = capget(&hdr, data); if (err) return err; + libbpf_mark_defined(data, sizeof(data)); if (old_caps) *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c index e1c1e521cca2..7253d5dc4bb2 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> +#include <bpf/libbpf_internal.h> #define nr_iters 2 @@ -31,6 +32,7 @@ void serial_test_bpf_obj_id(void) __u64 array_value; uid_t my_uid = getuid(); time_t now, load_time; + int tp_name_len; err = bpf_prog_get_fd_by_id(0); CHECK(err >= 0 || errno != ENOENT, @@ -122,6 +124,10 @@ void serial_test_bpf_obj_id(void) &info_len); load_time = (real_time_ts.tv_sec - boot_time_ts.tv_sec) + (prog_infos[i].load_time / nsec_per_sec); + if (!err) + libbpf_mark_defined(&map_ids[i], + prog_infos[i].nr_map_ids * + sizeof(map_ids[0])); if (CHECK(err || prog_infos[i].type != BPF_PROG_TYPE_RAW_TRACEPOINT || info_len != sizeof(struct bpf_prog_info) || @@ -163,6 +169,10 @@ void serial_test_bpf_obj_id(void) link_infos[i].raw_tracepoint.tp_name_len = sizeof(tp_name); err = bpf_obj_get_info_by_fd(bpf_link__fd(links[i]), &link_infos[i], &info_len); + if (!err) { + tp_name_len = link_infos[i].raw_tracepoint.tp_name_len; + libbpf_mark_defined(tp_name, tp_name_len + 1); + } if (CHECK(err || link_infos[i].type != BPF_LINK_TYPE_RAW_TRACEPOINT || link_infos[i].prog_id != prog_infos[i].id || diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c index e980188d4124..11f02f68e152 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c @@ -4,6 +4,7 @@ #include <linux/err.h> #include <netinet/tcp.h> #include <test_progs.h> +#include <bpf/libbpf_internal.h> #include "network_helpers.h" #include "bpf_dctcp.skel.h" #include "bpf_cubic.skel.h" @@ -39,6 +40,8 @@ static void *server(void *arg) ssize_t nr_sent = 0, bytes = 0; char batch[1500]; + libbpf_mark_defined(batch, sizeof(batch)); + fd = accept(lfd, NULL, NULL); while (fd == -1) { if (errno == EINTR) diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c index de1b5b9eb93a..ff6950404c02 100644 --- a/tools/testing/selftests/bpf/prog_tests/btf.c +++ b/tools/testing/selftests/bpf/prog_tests/btf.c @@ -20,6 +20,7 @@ #include <assert.h> #include <bpf/libbpf.h> #include <bpf/btf.h> +#include <bpf/libbpf_internal.h> #include "bpf_util.h" #include "../test_btf.h" @@ -4500,6 +4501,8 @@ static int test_btf_id(unsigned int test_num) /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */ info_len = sizeof(info[0]); err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len); + if (!err) + libbpf_mark_defined(user_btf[0], info[0].btf_size); if (CHECK(err, "errno:%d", errno)) { err = -1; goto done; @@ -4513,6 +4516,8 @@ static int test_btf_id(unsigned int test_num) ret = 0; err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len); + if (!err) + libbpf_mark_defined(user_btf[1], info[1].btf_size); if (CHECK(err || info[0].id != info[1].id || info[0].btf_size != info[1].btf_size || (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)), @@ -4639,6 +4644,8 @@ static void do_test_get_info(unsigned int test_num) ret = 0; err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len); + if (!err) + libbpf_mark_defined(user_btf, info.btf_size); if (CHECK(err || !info.id || info_len != sizeof(info) || info.btf_size != raw_btf_size || (ret = memcmp(raw_btf, user_btf, expected_nbytes)), @@ -4788,6 +4795,8 @@ static void do_test_file(unsigned int test_num) info.func_info = ptr_to_u64(func_info); err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); + if (!err) + libbpf_mark_defined(func_info, info.nr_func_info * rec_size); if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) { fprintf(stderr, "%s\n", btf_log_buf); @@ -6436,6 +6445,8 @@ static int test_get_finfo(const struct prog_info_raw_test *test, info.func_info_rec_size = rec_size; info.func_info = ptr_to_u64(func_info); err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); + if (!err) + libbpf_mark_defined(func_info, info.nr_func_info * rec_size); if (CHECK(err < 0, "invalid get info (2nd) errno:%d", errno)) { fprintf(stderr, "%s\n", btf_log_buf); err = -1; diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index d63a20fbed33..94f42b48e45d 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> +#include <bpf/libbpf_internal.h> #include <sys/time.h> #include <sys/resource.h> #include "test_send_signal_kern.skel.h" @@ -58,6 +59,7 @@ static void test_send_signal_common(struct perf_event_attr *attr, ASSERT_OK(setpriority(PRIO_PROCESS, 0, -20), "setpriority"); /* notify parent signal handler is installed */ + libbpf_mark_defined(buf, 1); ASSERT_EQ(write(pipe_c2p[1], buf, 1), 1, "pipe_write"); /* make sure parent enabled bpf program to send_signal */ diff --git a/tools/testing/selftests/bpf/prog_tests/tp_attach_query.c b/tools/testing/selftests/bpf/prog_tests/tp_attach_query.c index a479080533db..259bd8102907 100644 --- a/tools/testing/selftests/bpf/prog_tests/tp_attach_query.c +++ b/tools/testing/selftests/bpf/prog_tests/tp_attach_query.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> +#include <bpf/libbpf_internal.h> void serial_test_tp_attach_query(void) { @@ -65,6 +66,7 @@ void serial_test_tp_attach_query(void) if (i == 0) { /* check NULL prog array query */ query->ids_len = num_progs; + query->prog_cnt = 0; err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query); if (CHECK(err || query->prog_cnt != 0, "perf_event_ioc_query_bpf", @@ -109,6 +111,10 @@ void serial_test_tp_attach_query(void) query->ids_len = num_progs; err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query); + if (!err) + libbpf_mark_defined(query->ids, + query->prog_cnt * + sizeof(query->ids[0])); if (CHECK(err || query->prog_cnt != (i + 1), "perf_event_ioc_query_bpf", "err %d errno %d query->prog_cnt %u\n", diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c index 5e3a26b15ec6..2620c66533b9 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c @@ -14,6 +14,7 @@ #include <net/if.h> #include <linux/if_link.h> #include "test_progs.h" +#include "bpf/libbpf_internal.h" #include "network_helpers.h" #include <linux/if_bonding.h> #include <linux/limits.h> @@ -224,6 +225,8 @@ static int send_udp_packets(int vary_dst_ip) int i, s = -1; int ifindex; + libbpf_mark_defined(buf, sizeof(buf)); + s = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); if (!ASSERT_GE(s, 0, "socket")) goto err; diff --git a/tools/testing/selftests/bpf/xdp_synproxy.c b/tools/testing/selftests/bpf/xdp_synproxy.c index 6dbe0b745198..7667393bc7b5 100644 --- a/tools/testing/selftests/bpf/xdp_synproxy.c +++ b/tools/testing/selftests/bpf/xdp_synproxy.c @@ -12,6 +12,7 @@ #include <sys/types.h> #include <bpf/bpf.h> #include <bpf/libbpf.h> +#include <bpf/libbpf_internal.h> #include <net/if.h> #include <linux/if_link.h> #include <linux/limits.h> @@ -297,6 +298,7 @@ static int syncookie_open_bpf_maps(__u32 prog_id, int *values_map_fd, int *ports fprintf(stderr, "Error: bpf_obj_get_info_by_fd: %s\n", strerror(-err)); goto out; } + libbpf_mark_defined(map_ids, prog_info.nr_map_ids * sizeof(map_ids[0])); if (prog_info.nr_map_ids < 2) { fprintf(stderr, "Error: Found %u BPF maps, expected at least 2\n", -- 2.39.1