forked from Minki/linux
perf dso: Hold lock when accessing nsinfo
There may be threads racing to update dso->nsinfo: https://lore.kernel.org/linux-perf-users/CAP-5=fWZH20L4kv-BwVtGLwR=Em3AOOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/ Holding the dso->lock avoids use-after-free, memory leaks and other such bugs. Apply the fix in: https://lore.kernel.org/linux-perf-users/20211118193714.2293728-1-irogers@google.com/ of there being a missing nsinfo__put now that the accesses are data race free. Fixes test "Lookup mmap thread" when compiled with address sanitizer. Signed-off-by: Ian Rogers <irogers@google.com> Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexandre Truong <alexandre.truong@arm.com> Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Andres Freund <andres@anarazel.de> Cc: Andrii Nakryiko <andrii@kernel.org> Cc: André Almeida <andrealmeid@igalia.com> Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com> Cc: Christophe JAILLET <christophe.jaillet@wanadoo.fr> Cc: Colin Ian King <colin.king@intel.com> Cc: Dario Petrillo <dario.pk1@gmail.com> Cc: Darren Hart <dvhart@infradead.org> Cc: Dave Marchevsky <davemarchevsky@fb.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Fangrui Song <maskray@google.com> Cc: Hewenliang <hewenliang4@huawei.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jason Wang <wangborong@cdjrlc.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kim Phillips <kim.phillips@amd.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Martin Liška <mliska@suse.cz> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Nathan Chancellor <nathan@kernel.org> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Pavithra Gurushankar <gpavithrasha@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Quentin Monnet <quentin@isovalent.com> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Remi Bernon <rbernon@codeweavers.com> Cc: Riccardo Mancini <rickyman7@gmail.com> Cc: Song Liu <songliubraving@fb.com> Cc: Stephane Eranian <eranian@google.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Tom Rix <trix@redhat.com> Cc: Weiguo Li <liwg06@foxmail.com> Cc: Wenyu Liu <liuwenyu7@huawei.com> Cc: William Cohen <wcohen@redhat.com> Cc: Zechuan Chen <chenzechuan1@huawei.com> Cc: bpf@vger.kernel.org Cc: llvm@lists.linux.dev Cc: yaowenbin <yaowenbin1@huawei.com> Link: https://lore.kernel.org/r/20220826164242.43412-15-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d8e40b58ad
commit
e54dea69cd
@ -436,8 +436,10 @@ static struct dso *findnew_dso(int pid, int tid, const char *filename,
|
||||
}
|
||||
|
||||
if (dso) {
|
||||
mutex_lock(&dso->lock);
|
||||
nsinfo__put(dso->nsinfo);
|
||||
dso->nsinfo = nsi;
|
||||
mutex_unlock(&dso->lock);
|
||||
} else
|
||||
nsinfo__put(nsi);
|
||||
|
||||
@ -620,6 +622,7 @@ static int dso__read_build_id(struct dso *dso)
|
||||
if (dso->has_build_id)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&dso->lock);
|
||||
nsinfo__mountns_enter(dso->nsinfo, &nsc);
|
||||
if (filename__read_build_id(dso->long_name, &dso->bid) > 0)
|
||||
dso->has_build_id = true;
|
||||
@ -633,6 +636,7 @@ static int dso__read_build_id(struct dso *dso)
|
||||
free(new_name);
|
||||
}
|
||||
nsinfo__mountns_exit(&nsc);
|
||||
mutex_unlock(&dso->lock);
|
||||
|
||||
return dso->has_build_id ? 0 : -1;
|
||||
}
|
||||
|
@ -1697,6 +1697,7 @@ fallback:
|
||||
*/
|
||||
__symbol__join_symfs(filename, filename_size, dso->long_name);
|
||||
|
||||
mutex_lock(&dso->lock);
|
||||
if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) {
|
||||
char *new_name = filename_with_chroot(dso->nsinfo->pid,
|
||||
filename);
|
||||
@ -1705,6 +1706,7 @@ fallback:
|
||||
free(new_name);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&dso->lock);
|
||||
}
|
||||
|
||||
free(build_id_path);
|
||||
|
@ -898,11 +898,15 @@ static int filename__read_build_id_ns(const char *filename,
|
||||
static bool dso__build_id_mismatch(struct dso *dso, const char *name)
|
||||
{
|
||||
struct build_id bid;
|
||||
bool ret = false;
|
||||
|
||||
if (filename__read_build_id_ns(name, &bid, dso->nsinfo) < 0)
|
||||
return false;
|
||||
mutex_lock(&dso->lock);
|
||||
if (filename__read_build_id_ns(name, &bid, dso->nsinfo) >= 0)
|
||||
ret = !dso__build_id_equal(dso, &bid);
|
||||
|
||||
return !dso__build_id_equal(dso, &bid);
|
||||
mutex_unlock(&dso->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dso__cache_build_id(struct dso *dso, struct machine *machine,
|
||||
@ -941,8 +945,10 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine,
|
||||
if (!is_kallsyms && dso__build_id_mismatch(dso, name))
|
||||
goto out_free;
|
||||
|
||||
mutex_lock(&dso->lock);
|
||||
ret = build_id_cache__add_b(&dso->bid, name, dso->nsinfo,
|
||||
is_kallsyms, is_vdso, proper_name, root_dir);
|
||||
mutex_unlock(&dso->lock);
|
||||
out_free:
|
||||
free(allocated_name);
|
||||
return ret;
|
||||
|
@ -501,6 +501,7 @@ static int __open_dso(struct dso *dso, struct machine *machine)
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&dso->lock);
|
||||
if (machine)
|
||||
root_dir = machine->root_dir;
|
||||
|
||||
@ -541,6 +542,7 @@ static int __open_dso(struct dso *dso, struct machine *machine)
|
||||
unlink(name);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dso->lock);
|
||||
free(name);
|
||||
return fd;
|
||||
}
|
||||
@ -559,8 +561,11 @@ static int open_dso(struct dso *dso, struct machine *machine)
|
||||
int fd;
|
||||
struct nscookie nsc;
|
||||
|
||||
if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
|
||||
if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) {
|
||||
mutex_lock(&dso->lock);
|
||||
nsinfo__mountns_enter(dso->nsinfo, &nsc);
|
||||
mutex_unlock(&dso->lock);
|
||||
}
|
||||
fd = __open_dso(dso, machine);
|
||||
if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE)
|
||||
nsinfo__mountns_exit(&nsc);
|
||||
|
@ -181,7 +181,10 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
|
||||
if (!(prot & PROT_EXEC))
|
||||
dso__set_loaded(dso);
|
||||
}
|
||||
mutex_lock(&dso->lock);
|
||||
nsinfo__put(dso->nsinfo);
|
||||
dso->nsinfo = nsi;
|
||||
mutex_unlock(&dso->lock);
|
||||
|
||||
if (build_id__is_defined(bid)) {
|
||||
dso__set_build_id(dso, bid);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "color.h"
|
||||
#include "map.h"
|
||||
#include "maps.h"
|
||||
#include "mutex.h"
|
||||
#include "symbol.h"
|
||||
#include <api/fs/fs.h>
|
||||
#include "trace-event.h" /* For __maybe_unused */
|
||||
@ -180,8 +181,10 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
|
||||
|
||||
map = dso__new_map(target);
|
||||
if (map && map->dso) {
|
||||
mutex_lock(&map->dso->lock);
|
||||
nsinfo__put(map->dso->nsinfo);
|
||||
map->dso->nsinfo = nsinfo__get(nsi);
|
||||
mutex_unlock(&map->dso->lock);
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
|
@ -1791,6 +1791,7 @@ int dso__load(struct dso *dso, struct map *map)
|
||||
char newmapname[PATH_MAX];
|
||||
const char *map_path = dso->long_name;
|
||||
|
||||
mutex_lock(&dso->lock);
|
||||
perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0;
|
||||
if (perfmap) {
|
||||
if (dso->nsinfo && (dso__find_perf_map(newmapname,
|
||||
@ -1800,7 +1801,6 @@ int dso__load(struct dso *dso, struct map *map)
|
||||
}
|
||||
|
||||
nsinfo__mountns_enter(dso->nsinfo, &nsc);
|
||||
mutex_lock(&dso->lock);
|
||||
|
||||
/* check again under the dso->lock */
|
||||
if (dso__loaded(dso)) {
|
||||
|
Loading…
Reference in New Issue
Block a user