perf maps: Get map before returning in maps__find_next_entry
authorIan Rogers <irogers@google.com>
Sat, 10 Feb 2024 03:17:44 +0000 (19:17 -0800)
committerNamhyung Kim <namhyung@kernel.org>
Mon, 12 Feb 2024 20:35:41 +0000 (12:35 -0800)
Finding a map is done under a lock, returning the map without a
reference count means it can be removed without notice and causing
uses after free. Grab a reference count to the map within the lock
region and return this. Fix up locations that need a map__put
following this.

Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: James Clark <james.clark@arm.com>
Cc: Vincent Whitchurch <vincent.whitchurch@axis.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Song Liu <song@kernel.org>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Artem Savkov <asavkov@redhat.com>
Cc: bpf@vger.kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240210031746.4057262-5-irogers@google.com
tools/perf/util/machine.c
tools/perf/util/maps.c

index 7031f6fddcaef63c4ddcf995da3642db1f6d0021..4911734411b5334f2952ba5e11b9a4d8950b2956 100644 (file)
@@ -1761,8 +1761,10 @@ int machine__create_kernel_maps(struct machine *machine)
                struct map *next = maps__find_next_entry(machine__kernel_maps(machine),
                                                         machine__kernel_map(machine));
 
-               if (next)
+               if (next) {
                        machine__set_kernel_mmap(machine, start, map__start(next));
+                       map__put(next);
+               }
        }
 
 out_put:
index ea8fa684e8c60d1346422ed4c8c5c7f72dce695d..df0c8041899e3ea71673bb78aa0ceaae2c929824 100644 (file)
@@ -962,7 +962,7 @@ struct map *maps__find_next_entry(struct maps *maps, struct map *map)
        down_read(maps__lock(maps));
        i = maps__by_address_index(maps, map);
        if (i < maps__nr_maps(maps))
-               result = maps__maps_by_address(maps)[i]; // TODO: map__get
+               result = map__get(maps__maps_by_address(maps)[i]);
 
        up_read(maps__lock(maps));
        return result;