summaryrefslogtreecommitdiff
path: root/tools/perf/util/thread.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2019-07-09 13:22:03 +0200
committerIngo Molnar <mingo@kernel.org>2019-07-09 13:22:03 +0200
commitd1d59b817939821bee149e870ce7723f61ffb512 (patch)
treebb9fe7c29717fad3ff3dac63364b63dd86b740ac /tools/perf/util/thread.c
parent552a031ba12a4236be107a5b082a399237758a5d (diff)
parent686cbe9e5d88ad639bbe26d963e7d5dafa1c1c28 (diff)
downloadlinux-d1d59b817939821bee149e870ce7723f61ffb512.tar.gz
linux-d1d59b817939821bee149e870ce7723f61ffb512.tar.bz2
linux-d1d59b817939821bee149e870ce7723f61ffb512.zip
Merge tag 'perf-urgent-for-mingo-5.3-20190708-2' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/urgent fixes from Arnaldo Carvalho de Melo: core: Arnaldo Carvalho de Melo: - Allow references to thread objects after__machine_exit(), fixing a bug with 'perf sched lat' where that happens, i.e. after perf_session__delete() we still have references to threads that were in a linked list whose head was freed in perf_session__delete(), causing a segfault, fix it. Jiri Olsa: - Do not rely on errno values for precise_ip fallback, fixing the default use case for 'perf record' on some AMD servers, when no events are specified and we try to use "cycles:P", i.e. with the maximum precision level. BPF: Song Liu: - Assign proper ff->ph in perf_event__synthesize_features(), fixing a bug when using pipe mode, i.e. 'perf record -o -'. tools headers: Arnaldo Carvalho de Melo: - Sync kvm headers with the kernel sources perf tests: Seeteena Thoufeek: - Fix record+probe_libc_inet_pton.sh for powerpc64, where without the debuginfo package for the 'ping' utility we can't resolve its symbols, so admit getting "[unknown]" for that backtrace line. perf python: Arnaldo Carvalho de Melo: - Remove -fstack-protector-strong if clang doesn't have it, fixing the build with clang on fedora:30, oracleline:7, centos:7. perf jvmti: Jiri Olsa: - Address gcc string overflow warning for strncpy() build: Arnaldo Carvalho de Melo: - Check if gettid() is available before providing helper, as recent versions of glibc started to provide gettid(). Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/thread.c')
-rw-r--r--tools/perf/util/thread.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index aab7807d445f..3e29a4e8b5e6 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -125,10 +125,27 @@ void thread__put(struct thread *thread)
{
if (thread && refcount_dec_and_test(&thread->refcnt)) {
/*
- * Remove it from the dead_threads list, as last reference
- * is gone.
+ * Remove it from the dead threads list, as last reference is
+ * gone, if it is in a dead threads list.
+ *
+ * We may not be there anymore if say, the machine where it was
+ * stored was already deleted, so we already removed it from
+ * the dead threads and some other piece of code still keeps a
+ * reference.
+ *
+ * This is what 'perf sched' does and finally drops it in
+ * perf_sched__lat(), where it calls perf_sched__read_events(),
+ * that processes the events by creating a session and deleting
+ * it, which ends up destroying the list heads for the dead
+ * threads, but before it does that it removes all threads from
+ * it using list_del_init().
+ *
+ * So we need to check here if it is in a dead threads list and
+ * if so, remove it before finally deleting the thread, to avoid
+ * an use after free situation.
*/
- list_del_init(&thread->node);
+ if (!list_empty(&thread->node))
+ list_del_init(&thread->node);
thread__delete(thread);
}
}