BPF List
 help / color / mirror / Atom feed
* [PATCH v3 1/2] tools/bpf/bpftool: Reset vmlinux BTF after map commands
       [not found] <20260623072220.1421837-1-chenyichong@uniontech.com>
@ 2026-06-23  7:22 ` Yichong Chen
  2026-06-23  7:38   ` sashiko-bot
  2026-06-23  7:22 ` [PATCH v3 2/2] tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands Yichong Chen
  1 sibling, 1 reply; 4+ messages in thread
From: Yichong Chen @ 2026-06-23  7:22 UTC (permalink / raw)
  To: qmo, ast, daniel, andrii, eddyz87, memxor
  Cc: martin.lau, song, yonghong.song, jolsa, jiayuan.chen, bpf,
	linux-kernel, chenyichong

get_map_kv_btf() caches the vmlinux BTF object when a map uses
btf_vmlinux_value_type_id. map dump released that object when the
command completed, but left the global pointer stale.

The same cached object can also be returned to print_key_value(), which
freed it directly. That leaves btf_vmlinux dangling before the command
cleanup path runs.

Use free_map_kv_btf() for per-entry cleanup, and reset the cached
btf_vmlinux pointer when the map command releases the object. This keeps
batch mode from reusing a freed BTF object.

Fixes: 4e1ea33292ff ("bpftool: Support dumping a map with btf_vmlinux_value_type_id")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 tools/bpf/bpftool/map.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 7ebf7dbcfba4..a265ad3afbb0 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -790,6 +790,12 @@ static int maps_have_btf(int *fds, int nb_fds)
 
 static struct btf *btf_vmlinux;
 
+static void free_btf_vmlinux(void)
+{
+	btf__free(btf_vmlinux);
+	btf_vmlinux = NULL;
+}
+
 static int get_map_kv_btf(const struct bpf_map_info *info, struct btf **btf)
 {
 	int err = 0;
@@ -958,7 +964,7 @@ static int do_dump(int argc, char **argv)
 		close(fds[i]);
 exit_free:
 	free(fds);
-	btf__free(btf_vmlinux);
+	free_btf_vmlinux();
 	return err;
 }
 
@@ -1049,7 +1055,7 @@ static void print_key_value(struct bpf_map_info *info, void *key,
 		btf_wtr = get_btf_writer();
 		if (!btf_wtr) {
 			p_info("failed to create json writer for btf. falling back to plain output");
-			btf__free(btf);
+			free_map_kv_btf(btf);
 			btf = NULL;
 			print_entry_plain(info, key, value);
 		} else {
@@ -1065,7 +1071,7 @@ static void print_key_value(struct bpf_map_info *info, void *key,
 	} else {
 		print_entry_plain(info, key, value);
 	}
-	btf__free(btf);
+	free_map_kv_btf(btf);
 }
 
 static int do_lookup(int argc, char **argv)
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands
       [not found] <20260623072220.1421837-1-chenyichong@uniontech.com>
  2026-06-23  7:22 ` [PATCH v3 1/2] tools/bpf/bpftool: Reset vmlinux BTF after map commands Yichong Chen
@ 2026-06-23  7:22 ` Yichong Chen
  2026-06-23  7:36   ` sashiko-bot
  1 sibling, 1 reply; 4+ messages in thread
From: Yichong Chen @ 2026-06-23  7:22 UTC (permalink / raw)
  To: qmo, ast, daniel, andrii, eddyz87, memxor
  Cc: martin.lau, song, yonghong.song, jolsa, jiayuan.chen, bpf,
	linux-kernel, chenyichong

struct_ops frees the global btf_vmlinux object.

In batch mode, a later struct_ops command can reuse stale state.

Reset the BTF pointer and cached map info state.

Fixes: 65c93628599d ("bpftool: Add struct_ops support")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
---
 tools/bpf/bpftool/struct_ops.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tools/bpf/bpftool/struct_ops.c b/tools/bpf/bpftool/struct_ops.c
index aa43dead249c..4dba7c96e5f6 100644
--- a/tools/bpf/bpftool/struct_ops.c
+++ b/tools/bpf/bpftool/struct_ops.c
@@ -21,6 +21,15 @@ static __u32 map_info_alloc_len;
 static struct btf *btf_vmlinux;
 static __s32 map_info_type_id;
 
+static void free_btf_vmlinux(void)
+{
+	btf__free(btf_vmlinux);
+	btf_vmlinux = NULL;
+	map_info_type = NULL;
+	map_info_alloc_len = 0;
+	map_info_type_id = 0;
+}
+
 struct res {
 	unsigned int nr_maps;
 	unsigned int nr_errs;
@@ -642,7 +651,7 @@ int do_struct_ops(int argc, char **argv)
 
 	err = cmd_select(cmds, argc, argv, do_help);
 
-	btf__free(btf_vmlinux);
+	free_btf_vmlinux();
 
 	return err;
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 2/2] tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands
  2026-06-23  7:22 ` [PATCH v3 2/2] tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands Yichong Chen
@ 2026-06-23  7:36   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-23  7:36 UTC (permalink / raw)
  To: Yichong Chen; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Medium] Severe memory leak of the btf_vmlinux object during cgroup tree traversal or repeated cgroup commands in batch mode.
--

commit f6cbf97292c743366f83c8ee625e792b14e79b4f
Author: Yichong Chen <chenyichong@uniontech.com>

tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands

struct_ops frees the global btf_vmlinux object. In batch mode, a later
struct_ops command can reuse stale state. This resets the BTF pointer
and cached map info state.

> diff --git a/tools/bpf/bpftool/struct_ops.c b/tools/bpf/bpftool/struct_ops.c
> index aa43dead249cb..4dba7c96e5f60 100644
> --- a/tools/bpf/bpftool/struct_ops.c
> +++ b/tools/bpf/bpftool/struct_ops.c
[ ... ]
> @@ -642,7 +651,7 @@ int do_struct_ops(int argc, char **argv)
>  
>  	err = cmd_select(cmds, argc, argv, do_help);
>  
> -	btf__free(btf_vmlinux);
> +	free_btf_vmlinux();
>  

[Severity: Medium]
This is a pre-existing issue, but while you are fixing the batch mode state
for struct_ops, could a similar btf_vmlinux memory leak be occurring in
cgroup commands?

Looking at tools/bpf/bpftool/cgroup.c:do_show():

	btf_vmlinux = libbpf_find_kernel_btf();

In batch mode, does every cgroup show command overwrite the global
btf_vmlinux pointer without freeing the previous BTF object?

Similarly, in tools/bpf/bpftool/cgroup.c:do_show_tree_fn():

	btf_vmlinux = libbpf_find_kernel_btf();

During a cgroup tree command, nftw() calls this function for every cgroup
directory. Does it load a new kernel BTF object each time and overwrite the
global pointer without freeing the previous one, creating a leak that scales
with the size of the cgroup hierarchy?

>  	return err;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260623072220.1421837-1-chenyichong@uniontech.com?part=2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] tools/bpf/bpftool: Reset vmlinux BTF after map commands
  2026-06-23  7:22 ` [PATCH v3 1/2] tools/bpf/bpftool: Reset vmlinux BTF after map commands Yichong Chen
@ 2026-06-23  7:38   ` sashiko-bot
  0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-23  7:38 UTC (permalink / raw)
  To: Yichong Chen; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Memory leak of btf_vmlinux in cgroup.c subcommands
--

commit 20f01631a8680469e5ce832fb9e313bcd34e8d13
Author: Yichong Chen <chenyichong@uniontech.com>

tools/bpf/bpftool: Reset vmlinux BTF after map commands

get_map_kv_btf() caches the vmlinux BTF object when a map uses
btf_vmlinux_value_type_id. This commit introduces free_btf_vmlinux() to
properly clean up the cached btf_vmlinux pointer when the map command releases
the object, keeping batch mode from reusing a freed BTF object.

> diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
> index 71a45d96617ed..6b9649294ca1a 100644
> --- a/tools/bpf/bpftool/map.c
> +++ b/tools/bpf/bpftool/map.c
> @@ -790,6 +790,12 @@ static int maps_have_btf(int *fds, int nb_fds)
>  
>  static struct btf *btf_vmlinux;
>  
> +static void free_btf_vmlinux(void)
> +{
> +	btf__free(btf_vmlinux);
> +	btf_vmlinux = NULL;
> +}

[Severity: High]
This isn't a bug introduced by this patch, but since you are fixing the
btf_vmlinux leak here, could there be a similar memory leak of btf_vmlinux in
tools/bpf/bpftool/cgroup.c?

In do_show_tree_fn() and do_show() in cgroup.c, a new BTF object is allocated
with libbpf_find_kernel_btf() and unconditionally assigned to btf_vmlinux
without freeing the previous instance:

tools/bpf/bpftool/cgroup.c:do_show_tree_fn() {
    ...
    btf_vmlinux = libbpf_find_kernel_btf();
    ...
}

Since do_show_tree_fn() is called for each cgroup during nftw() traversal,
could this repeatedly leak the kernel BTF object (which can be several
megabytes) on each cgroup processed? This seems like it could lead to an
out-of-memory crash when running the "bpftool cgroup tree" command on a system
with a moderate number of cgroups.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260623072220.1421837-1-chenyichong@uniontech.com?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-23  7:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260623072220.1421837-1-chenyichong@uniontech.com>
2026-06-23  7:22 ` [PATCH v3 1/2] tools/bpf/bpftool: Reset vmlinux BTF after map commands Yichong Chen
2026-06-23  7:38   ` sashiko-bot
2026-06-23  7:22 ` [PATCH v3 2/2] tools/bpf/bpftool: Reset vmlinux BTF after struct_ops commands Yichong Chen
2026-06-23  7:36   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox