[PATCH bpf-next v1 05/14] selftests/bpf: Fix memory leaks in tests

Ihor Solodrai posted 14 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH bpf-next v1 05/14] selftests/bpf: Fix memory leaks in tests
Posted by Ihor Solodrai 1 month, 2 weeks ago
Fix trivial memory leaks detected by userspace ASAN:
  - htab_update: free value buffer in test_reenter_update cleanup
  - test_xsk: delete old pkt_stream before replacing in stats tests
  - testing_helpers: free buffer allocated by getline() in
    parse_test_list_file

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/prog_tests/htab_update.c | 1 +
 tools/testing/selftests/bpf/prog_tests/test_xsk.c    | 2 ++
 tools/testing/selftests/bpf/testing_helpers.c        | 1 +
 3 files changed, 4 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/htab_update.c b/tools/testing/selftests/bpf/prog_tests/htab_update.c
index d0b405eb2966..ea1a6766fbe9 100644
--- a/tools/testing/selftests/bpf/prog_tests/htab_update.c
+++ b/tools/testing/selftests/bpf/prog_tests/htab_update.c
@@ -61,6 +61,7 @@ static void test_reenter_update(void)
 
 	ASSERT_EQ(skel->bss->update_err, -EDEADLK, "no reentrancy");
 out:
+	free(value);
 	htab_update__destroy(skel);
 }
 
diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
index bab4a31621c7..dac90ddcdd7e 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c
@@ -2005,6 +2005,7 @@ int testapp_stats_rx_full(struct test_spec *test)
 {
 	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
 		return TEST_FAILURE;
+	pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
 	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
 
 	test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
@@ -2017,6 +2018,7 @@ int testapp_stats_fill_empty(struct test_spec *test)
 {
 	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
 		return TEST_FAILURE;
+	pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
 	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
 
 	test->ifobj_rx->use_fill_ring = false;
diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c
index 16eb37e5bad6..66af0d13751a 100644
--- a/tools/testing/selftests/bpf/testing_helpers.c
+++ b/tools/testing/selftests/bpf/testing_helpers.c
@@ -212,6 +212,7 @@ int parse_test_list_file(const char *path,
 			break;
 	}
 
+	free(buf);
 	fclose(f);
 	return err;
 }
-- 
2.53.0
Re: [PATCH bpf-next v1 05/14] selftests/bpf: Fix memory leaks in tests
Posted by Eduard Zingerman 1 month, 2 weeks ago
On Wed, 2026-02-11 at 17:13 -0800, Ihor Solodrai wrote:

[...]

> @@ -2005,6 +2005,7 @@ int testapp_stats_rx_full(struct test_spec *test)
>  {
>  	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
>  		return TEST_FAILURE;
> +	pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);

This one is a bit strange.
pkt_stream_replace() allocates test->ifobj_rx->xsk->pkt_stream and
test->ifobj_tx->xsk->pkt_stream (rx and tx streams), and proceeds to
immediately free the rx stream and allocate another one for it.
The following seem to be a better fit:

  -       if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
  -               return TEST_FAILURE;
  -       pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
  +       test->ifobj_tx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
          test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);

(I effectively inlined pkt_stream_replace()).

>  	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
>  
>  	test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
> @@ -2017,6 +2018,7 @@ int testapp_stats_fill_empty(struct test_spec *test)
>  {
>  	if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE))
>  		return TEST_FAILURE;
> +	pkt_stream_delete(test->ifobj_rx->xsk->pkt_stream);
>  	test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);

Same here.

[...]