[PATCH 1/1] perf tool: fix handling NULL al->maps returned from thread__find_map

From: Casey Chen
Date: Mon Jul 08 2024 - 19:23:34 EST


With 0dd5041c9a0e ("perf addr_location: Add init/exit/copy functions"),
thread__find_map() would return with al->maps or al->map being NULL
when cpumode is 3 (macro PERF_RECORD_MISC_HYPERVISOR),
later deferencing on it would crash.

Fix callers of thread__find_map() or thread__find_symbol() to handle
this.
---
tools/perf/arch/powerpc/util/skip-callchain-idx.c | 10 ++++++----
tools/perf/util/machine.c | 5 +++++
tools/perf/util/unwind-libdw.c | 6 ++++--
3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index 5f3edb3004d8..25b0804df4c4 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -255,13 +255,14 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)

thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);

- if (al.map)
- dso = map__dso(al.map);
+ if (!al.map)
+ goto out;
+
+ dso = map__dso(al.map);

if (!dso) {
pr_debug("%" PRIx64 " dso is NULL\n", ip);
- addr_location__exit(&al);
- return skip_slot;
+ goto out;
}

rc = check_return_addr(dso, map__start(al.map), ip);
@@ -282,6 +283,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain)
skip_slot = 3;
}

+out:
addr_location__exit(&al);
return skip_slot;
}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 8477edefc299..fa4037d7f3d4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2098,7 +2098,12 @@ static int add_callchain_ip(struct thread *thread,
}
goto out;
}
+
thread__find_symbol(thread, *cpumode, ip, &al);
+ if (!al.maps || !al.map) {
+ err = 1;
+ goto out;
+ }
}

if (al.sym != NULL) {
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index b38d322734b4..fb038ef55be2 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -53,8 +53,10 @@ static int __report_module(struct addr_location *al, u64 ip,
*/
thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al);

- if (al->map)
- dso = map__dso(al->map);
+ if (!al->map)
+ return -1;
+
+ dso = map__dso(al->map);

if (!dso)
return 0;
--
2.45.2