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. 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: 4e1ea33292 ("bpftool: Support dumping a map with btf_vmlinux_value_type_id")
Signed-off-by: Yichong Chen <chenyichong@uniontech.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://lore.kernel.org/bpf/9072F43B3F74DF91+20260624025055.1574875-2-chenyichong@uniontech.com
This commit is contained in:
Yichong Chen 2026-06-24 10:50:54 +08:00 committed by Andrii Nakryiko
parent a954c9e316
commit 66d7e39e49

View File

@ -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)