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


Reply via email to