From: Jiri Olsa <olsajiri@gmail.com>
To: Ihor Solodrai <ihor.solodrai@linux.dev>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Amery Hung" <ameryhung@gmail.com>,
"Mykyta Yatsenko" <yatsenko@meta.com>,
"Alexis Lothoré" <alexis.lothore@bootlin.com>,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel-team@meta.com
Subject: Re: [PATCH bpf-next v1 04/14] selftests/bpf: Refactor bpf_get_ksyms() trace helper
Date: Thu, 12 Feb 2026 12:29:04 +0100 [thread overview]
Message-ID: <aY25gB6NDmlPJPUB@krava> (raw)
In-Reply-To: <20260212011356.3266753-5-ihor.solodrai@linux.dev>
On Wed, Feb 11, 2026 at 05:13:46PM -0800, Ihor Solodrai wrote:
> ASAN reported a memory leak in bpf_get_ksyms(): it allocates a struct
> ksyms internally and never frees it.
>
> Moe struct ksyms to trace_helpers.h and return it from the
> bpf_get_ksyms(), giving ownership to the caller. Add filtered_syms and
> filtered_cnt fields to the ksyms to hold the filtered array of
> symbols, previously returned by bpf_get_ksyms().
>
> Fixup the call sites: kprobe_multi_test and bench_trigger.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---
> .../selftests/bpf/benchs/bench_trigger.c | 9 ++++----
> .../bpf/prog_tests/kprobe_multi_test.c | 12 ++++------
> tools/testing/selftests/bpf/trace_helpers.c | 23 ++++++++++---------
> tools/testing/selftests/bpf/trace_helpers.h | 11 +++++++--
> 4 files changed, 30 insertions(+), 25 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> index aeec9edd3851..7231b88cf21a 100644
> --- a/tools/testing/selftests/bpf/benchs/bench_trigger.c
> +++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c
> @@ -230,8 +230,7 @@ static void trigger_fentry_setup(void)
> static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
> {
> LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
> - char **syms = NULL;
> - size_t cnt = 0;
> + struct ksyms *ksyms = NULL;
>
> /* Some recursive functions will be skipped in
> * bpf_get_ksyms -> skip_entry, as they can introduce sufficient
> @@ -241,13 +240,13 @@ static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe)
> * So, don't run the kprobe-multi-all and kretprobe-multi-all on
> * a debug kernel.
> */
> - if (bpf_get_ksyms(&syms, &cnt, true)) {
> + if (bpf_get_ksyms(&ksyms, true)) {
> fprintf(stderr, "failed to get ksyms\n");
> exit(1);
> }
>
> - opts.syms = (const char **) syms;
> - opts.cnt = cnt;
> + opts.syms = (const char **)ksyms->filtered_syms;
> + opts.cnt = ksyms->filtered_cnt;
> opts.retprobe = kretprobe;
> /* attach empty to all the kernel functions except bpf_get_numa_node_id. */
> if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) {
hi,
missing free_kallsyms_local call in here ?
> diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
> index 9caef222e528..f81dcd609ee9 100644
> --- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
> +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
> @@ -456,25 +456,23 @@ static void test_kprobe_multi_bench_attach(bool kernel)
> {
> LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
> struct kprobe_multi_empty *skel = NULL;
> - char **syms = NULL;
> - size_t cnt = 0;
> + struct ksyms *ksyms = NULL;
>
> - if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, kernel), "bpf_get_ksyms"))
> + if (!ASSERT_OK(bpf_get_ksyms(&ksyms, kernel), "bpf_get_ksyms"))
> return;
>
> skel = kprobe_multi_empty__open_and_load();
> if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
> goto cleanup;
>
> - opts.syms = (const char **) syms;
> - opts.cnt = cnt;
> + opts.syms = (const char **)ksyms->filtered_syms;
> + opts.cnt = ksyms->filtered_cnt;
>
> do_bench_test(skel, &opts);
>
> cleanup:
> kprobe_multi_empty__destroy(skel);
> - if (syms)
> - free(syms);
> + free_kallsyms_local(ksyms);
> }
>
> static void test_kprobe_multi_bench_attach_addr(bool kernel)
> diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
> index eeaab7013ca2..0e63daf83ed5 100644
> --- a/tools/testing/selftests/bpf/trace_helpers.c
> +++ b/tools/testing/selftests/bpf/trace_helpers.c
> @@ -24,12 +24,6 @@
> #define TRACEFS_PIPE "/sys/kernel/tracing/trace_pipe"
> #define DEBUGFS_PIPE "/sys/kernel/debug/tracing/trace_pipe"
>
> -struct ksyms {
> - struct ksym *syms;
> - size_t sym_cap;
> - size_t sym_cnt;
> -};
> -
> static struct ksyms *ksyms;
> static pthread_mutex_t ksyms_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> @@ -54,6 +48,8 @@ void free_kallsyms_local(struct ksyms *ksyms)
> if (!ksyms)
> return;
>
> + free(ksyms->filtered_syms);
> +
> if (!ksyms->syms) {
> free(ksyms);
> return;
> @@ -610,7 +606,7 @@ static int search_kallsyms_compare(const void *p1, const struct ksym *p2)
> return compare_name(p1, p2->name);
> }
>
> -int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
> +int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel)
> {
> size_t cap = 0, cnt = 0;
> char *name = NULL, *ksym_name, **syms = NULL;
> @@ -637,8 +633,10 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
> else
> f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");
>
> - if (!f)
> + if (!f) {
> + free_kallsyms_local(ksyms);
> return -EINVAL;
> + }
>
> map = hashmap__new(symbol_hash, symbol_equal, NULL);
> if (IS_ERR(map)) {
> @@ -679,15 +677,18 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel)
> syms[cnt++] = ksym_name;
> }
>
> - *symsp = syms;
> - *cntp = cnt;
> + ksyms->filtered_syms = syms;
> + ksyms->filtered_cnt = cnt;
> + *ksymsp = ksyms;
>
> error:
> free(name);
> fclose(f);
> hashmap__free(map);
> - if (err)
> + if (err) {
> free(syms);
> + free_kallsyms_local(ksyms);
> + }
I think we could just call free_kallsyms_local unconditionally in here
and fix callers to free syms pointer? seems easier than adding filtered*
fields to ksyms
thanks,
jirak
> return err;
> }
>
> diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
> index a5576b2dfc26..d5bf1433675d 100644
> --- a/tools/testing/selftests/bpf/trace_helpers.h
> +++ b/tools/testing/selftests/bpf/trace_helpers.h
> @@ -23,7 +23,14 @@ struct ksym {
> long addr;
> char *name;
> };
> -struct ksyms;
> +
> +struct ksyms {
> + struct ksym *syms;
> + size_t sym_cap;
> + size_t sym_cnt;
> + char **filtered_syms;
> + size_t filtered_cnt;
> +};
>
> typedef int (*ksym_cmp_t)(const void *p1, const void *p2);
> typedef int (*ksym_search_cmp_t)(const void *p1, const struct ksym *p2);
> @@ -53,7 +60,7 @@ ssize_t get_rel_offset(uintptr_t addr);
>
> int read_build_id(const char *path, char *build_id, size_t size);
>
> -int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel);
> +int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel);
> int bpf_get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel);
>
> #endif
> --
> 2.53.0
>
>
next prev parent reply other threads:[~2026-02-12 11:29 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 1:13 [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN Ihor Solodrai
2026-02-12 1:13 ` [PATCH bpf-next v1 01/14] selftests/bpf: Pass through build flags to bpftool and resolve_btfids Ihor Solodrai
2026-02-12 2:39 ` Alexei Starovoitov
2026-02-12 3:08 ` Ihor Solodrai
2026-02-13 0:08 ` Ihor Solodrai
2026-02-12 1:13 ` [PATCH bpf-next v1 02/14] resolve_btfids: Fix memory leaks reported by ASAN Ihor Solodrai
2026-02-12 11:28 ` Jiri Olsa
2026-02-12 1:13 ` [PATCH bpf-next v1 03/14] selftests/bpf: Add DENYLIST.asan Ihor Solodrai
2026-02-12 1:13 ` [PATCH bpf-next v1 04/14] selftests/bpf: Refactor bpf_get_ksyms() trace helper Ihor Solodrai
2026-02-12 11:29 ` Jiri Olsa [this message]
2026-02-17 20:42 ` Ihor Solodrai
2026-02-18 13:14 ` Jiri Olsa
2026-02-13 9:56 ` Alexis Lothoré
2026-02-12 1:13 ` [PATCH bpf-next v1 05/14] selftests/bpf: Fix memory leaks in tests Ihor Solodrai
2026-02-12 23:08 ` Eduard Zingerman
2026-02-12 1:13 ` [PATCH bpf-next v1 06/14] selftests/bpf: Fix cleanup in check_fd_array_cnt__fd_array_too_big() Ihor Solodrai
2026-02-12 23:17 ` Eduard Zingerman
2026-02-12 1:13 ` [PATCH bpf-next v1 07/14] veristat: Fix a memory leak for preset ENUMERATOR Ihor Solodrai
2026-02-12 13:37 ` Mykyta Yatsenko
2026-02-12 1:13 ` [PATCH bpf-next v1 08/14] selftests/bpf: Fix use-after-free in xdp_metadata test Ihor Solodrai
2026-02-12 13:40 ` Mykyta Yatsenko
2026-02-12 1:13 ` [PATCH bpf-next v1 09/14] selftests/bpf: Fix double thread join in uprobe_multi_test Ihor Solodrai
2026-02-12 11:29 ` Jiri Olsa
2026-02-12 14:49 ` Mykyta Yatsenko
2026-02-13 16:48 ` Jiri Olsa
2026-02-12 1:13 ` [PATCH bpf-next v1 10/14] selftests/bpf: Fix resource leaks caused by missing cleanups Ihor Solodrai
2026-02-13 0:45 ` Eduard Zingerman
2026-02-12 1:13 ` [PATCH bpf-next v1 11/14] selftests/bpf: Free bpf_object in test_sysctl Ihor Solodrai
2026-02-13 0:54 ` Eduard Zingerman
2026-02-12 1:13 ` [PATCH bpf-next v1 12/14] selftests/bpf: Fix array bounds warning in jit_disasm_helpers Ihor Solodrai
2026-02-13 1:02 ` Eduard Zingerman
2026-02-12 1:13 ` [PATCH bpf-next v1 13/14] selftests/bpf: Fix out-of-bounds array access bugs reported by ASAN Ihor Solodrai
2026-02-13 1:11 ` Eduard Zingerman
2026-02-17 23:27 ` Ihor Solodrai
2026-02-12 1:13 ` [PATCH bpf-next v1 14/14] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path() Ihor Solodrai
2026-02-12 15:03 ` Mykyta Yatsenko
2026-02-13 10:36 ` Alexis Lothoré
2026-02-12 22:00 ` [PATCH bpf-next v1 00/14] selftests/bpf: Fixes for userspace ASAN Eduard Zingerman
2026-02-12 23:57 ` Ihor Solodrai
2026-02-13 0:23 ` Eduard Zingerman
2026-02-13 16:13 ` Ihor Solodrai
2026-02-13 18:06 ` Eduard Zingerman
2026-02-12 23:26 ` Eduard Zingerman
2026-02-13 17:56 ` Ihor Solodrai
2026-02-13 18:09 ` Eduard Zingerman
2026-02-13 18:29 ` Ihor Solodrai
2026-02-13 18:35 ` Eduard Zingerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aY25gB6NDmlPJPUB@krava \
--to=olsajiri@gmail.com \
--cc=alexis.lothore@bootlin.com \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=yatsenko@meta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.