[PATCH bpf v2 11/15] selftests/bpf: Free bpf_object in test_sysctl

Ihor Solodrai posted 15 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH bpf v2 11/15] selftests/bpf: Free bpf_object in test_sysctl
Posted by Ihor Solodrai 1 month, 2 weeks ago
ASAN reported a resource leak due to the bpf_object not being tracked
in test_sysctl. Add obj field to struct sysctl_test to properly clean
up bpf_object if a program was loaded from a file.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../testing/selftests/bpf/prog_tests/test_sysctl.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
index 273dd41ca09e..4349b846f1b3 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c
@@ -27,6 +27,7 @@ struct sysctl_test {
 		OP_EPERM,
 		SUCCESS,
 	} result;
+	struct bpf_object *obj;
 };
 
 static struct sysctl_test tests[] = {
@@ -1471,14 +1472,16 @@ static int load_sysctl_prog_file(struct sysctl_test *test)
 		return -1;
 	}
 
+	test->obj = obj;
 	return prog_fd;
 }
 
 static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
 {
-		return test->prog_file
-			? load_sysctl_prog_file(test)
-			: load_sysctl_prog_insns(test, sysctl_path);
+	if (test->prog_file)
+		return load_sysctl_prog_file(test);
+	test->obj = NULL;
+	return load_sysctl_prog_insns(test, sysctl_path);
 }
 
 static int access_sysctl(const char *sysctl_path,
@@ -1573,7 +1576,10 @@ static int run_test_case(int cgfd, struct sysctl_test *test)
 	/* Detaching w/o checking return code: best effort attempt. */
 	if (progfd != -1)
 		bpf_prog_detach(cgfd, atype);
-	close(progfd);
+	if (test->obj)
+		bpf_object__close(test->obj);
+	else if (progfd != -1)
+		close(progfd);
 	printf("[%s]\n", err ? "FAIL" : "PASS");
 	return err;
 }
-- 
2.53.0
Re: [PATCH bpf v2 11/15] selftests/bpf: Free bpf_object in test_sysctl
Posted by Eduard Zingerman 1 month, 1 week ago
On Tue, 2026-02-17 at 16:30 -0800, Ihor Solodrai wrote:
> ASAN reported a resource leak due to the bpf_object not being tracked
> in test_sysctl. Add obj field to struct sysctl_test to properly clean
> up bpf_object if a program was loaded from a file.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

> @@ -1471,14 +1472,16 @@ static int load_sysctl_prog_file(struct sysctl_test *test)
>  		return -1;
>  	}
>  
> +	test->obj = obj;
>  	return prog_fd;
>  }
>  
>  static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
>  {
> -		return test->prog_file
> -			? load_sysctl_prog_file(test)
> -			: load_sysctl_prog_insns(test, sysctl_path);
> +	if (test->prog_file)
> +		return load_sysctl_prog_file(test);
> +	test->obj = NULL;

Nit: is this necessary? The way `tests` is defined ->obj will be NULL anyway.
     Looks a bit asymmetrical.

> +	return load_sysctl_prog_insns(test, sysctl_path);
>  }
>  
>  static int access_sysctl(const char *sysctl_path,
> @@ -1573,7 +1576,10 @@ static int run_test_case(int cgfd, struct sysctl_test *test)
>  	/* Detaching w/o checking return code: best effort attempt. */
>  	if (progfd != -1)
>  		bpf_prog_detach(cgfd, atype);
> -	close(progfd);
> +	if (test->obj)
> +		bpf_object__close(test->obj);
> +	else if (progfd != -1)
> +		close(progfd);

Nit: close(-1) works fine, as well as bpf_object__close(NULL),
     so there is no need for 'if' statements here.

>  	printf("[%s]\n", err ? "FAIL" : "PASS");
>  	return err;
>  }