The kernel copies bpf_map_info from userspace and only fills in the BTF fields when a map has BTF. Reusing the structure for a later map without BTF therefore retains the preceding map's BTF IDs.
Clear the structure and restore its length before each query in map listing, named-map listing, BTF detection and dumping. This prevents reporting stale BTF IDs, choosing BTF output for mixed map selections, and formatting a map with another map's key and value types. Reported-by: Quentin Monnet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Assisted-by: LLM Signed-off-by: Tianyi Chen <[email protected]> --- tools/bpf/bpftool/map.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index 20d59eab09a1..f84311fa640d 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -647,6 +647,8 @@ static int do_show_subset(int argc, char **argv) if (json_output && nb_fds > 1) jsonw_start_array(json_wtr); /* root array */ for (i = 0; i < nb_fds; i++) { + memset(&info, 0, sizeof(info)); + len = sizeof(info); err = bpf_map_get_info_by_fd(fds[i], &info, &len); if (err) { p_err("can't get map info: %s", @@ -718,6 +720,8 @@ static int do_show(int argc, char **argv) break; } + memset(&info, 0, sizeof(info)); + len = sizeof(info); err = bpf_map_get_info_by_fd(fd, &info, &len); if (err) { p_err("can't get map info: %s", strerror(errno)); @@ -774,6 +778,8 @@ static int maps_have_btf(int *fds, int nb_fds) int err, i; for (i = 0; i < nb_fds; i++) { + memset(&info, 0, sizeof(info)); + len = sizeof(info); err = bpf_map_get_info_by_fd(fds[i], &info, &len); if (err) { p_err("can't get map info: %s", strerror(errno)); @@ -952,6 +958,8 @@ static int do_dump(int argc, char **argv) if (wtr && nb_fds > 1) jsonw_start_array(wtr); /* root array */ for (i = 0; i < nb_fds; i++) { + memset(&info, 0, sizeof(info)); + len = sizeof(info); if (bpf_map_get_info_by_fd(fds[i], &info, &len)) { p_err("can't get map info: %s", strerror(errno)); err = -1; -- 2.55.0
