diff mbox series

[bpf-next,9/9] selftests/bpf: Add MSan annotations

Message ID 20230208205642.270567-10-iii@linux.ibm.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series selftests/bpf: Add Memory Sanitizer support | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 19 maintainers not CCed: linux-kselftest@vger.kernel.org john.fastabend@gmail.com eddyz87@gmail.com jthinz@mailbox.tu-berlin.de sdf@google.com jolsa@kernel.org kuba@kernel.org netdev@vger.kernel.org song@kernel.org mykolal@fb.com davem@davemloft.net martin.lau@linux.dev haoluo@google.com shuah@kernel.org deso@posteo.net kpsingh@kernel.org geliang.tang@suse.com yhs@fb.com hawk@kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 179 lines checked
netdev/kdoc success Errors and warnings before: 2 this patch: 2
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-7 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32 on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-37 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-38 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-14 fail Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 fail Logs for test_progs_no_alu32_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_progs_parallel on s390x with gcc

Commit Message

Ilya Leoshkevich Feb. 8, 2023, 8:56 p.m. UTC
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@linux.ibm.com>
---
 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(+)

Comments

Andrii Nakryiko Feb. 9, 2023, 1:34 a.m. UTC | #1
On Wed, Feb 8, 2023 at 12:57 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> 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.

yeah, bpf_obj_get_info_by_fd() is quite bad from usability standpoint.
I think we should add bpf_get_{map,prog,link,btf}_info_by_fd()
wrappers and try to use them. That will allow to specify correct
expected struct types, we'll be able to mark initialized memory
properly. We already have bpf_{map,prog,btf,link}_get_fd_by_id()
family, so having similar for getting info seems fitting (even if
underlying bpf() command is generic).

Thoughts?

>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>  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(+)
>

[...]
Ilya Leoshkevich Feb. 9, 2023, 10:30 a.m. UTC | #2
On Wed, 2023-02-08 at 17:34 -0800, Andrii Nakryiko wrote:
> On Wed, Feb 8, 2023 at 12:57 PM Ilya Leoshkevich <iii@linux.ibm.com>
> wrote:
> > 
> > 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.
> 
> yeah, bpf_obj_get_info_by_fd() is quite bad from usability
> standpoint.
> I think we should add bpf_get_{map,prog,link,btf}_info_by_fd()
> wrappers and try to use them. That will allow to specify correct
> expected struct types, we'll be able to mark initialized memory
> properly. We already have bpf_{map,prog,btf,link}_get_fd_by_id()
> family, so having similar for getting info seems fitting (even if
> underlying bpf() command is generic).
> 
> Thoughts?

Sounds good to me, I will give it a try.

> > 
> > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> > ---
> >  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 mbox series

Patch

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",