Messages in this thread Patch in this message | | | Date | Tue, 25 Jan 2022 12:46:01 -0800 | Subject | [PATCH v2 3/4] perf dso: Hold lock when accessing nsinfo | From | Ian Rogers <> |
| |
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.
Signed-off-by: Ian Rogers <irogers@google.com> --- tools/perf/builtin-inject.c | 4 ++++ tools/perf/util/dso.c | 5 ++++- tools/perf/util/map.c | 3 +++ tools/perf/util/probe-event.c | 2 ++ tools/perf/util/symbol.c | 2 +- 5 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index fbf43a454cba..bede332bf0e2 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -363,8 +363,10 @@ static struct dso *findnew_dso(int pid, int tid, const char *filename, } if (dso) { + BUG_ON(pthread_mutex_lock(&dso->lock) != 0); nsinfo__put(dso->nsinfo); dso->nsinfo = nsi; + pthread_mutex_unlock(&dso->lock); } else nsinfo__put(nsi); @@ -547,7 +549,9 @@ static int dso__read_build_id(struct dso *dso) if (dso->has_build_id) return 0; + BUG_ON(pthread_mutex_lock(&dso->lock) != 0); nsinfo__mountns_enter(dso->nsinfo, &nsc); + pthread_mutex_unlock(&dso->lock); if (filename__read_build_id(dso->long_name, &dso->bid) > 0) dso->has_build_id = true; nsinfo__mountns_exit(&nsc); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 6beccffeef7b..b2f570adba35 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -548,8 +548,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) { + BUG_ON(pthread_mutex_lock(&dso->lock) != 0); nsinfo__mountns_enter(dso->nsinfo, &nsc); + pthread_mutex_unlock(&dso->lock); + } fd = __open_dso(dso, machine); if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) nsinfo__mountns_exit(&nsc); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 8af693d9678c..ae99b52502d5 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -192,7 +192,10 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (!(prot & PROT_EXEC)) dso__set_loaded(dso); } + BUG_ON(pthread_mutex_lock(&dso->lock) != 0); + nsinfo__put(dso->nsinfo); dso->nsinfo = nsi; + pthread_mutex_unlock(&dso->lock); if (build_id__is_defined(bid)) dso__set_build_id(dso, bid); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a834918a0a0d..7444e689ece7 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -180,8 +180,10 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user) map = dso__new_map(target); if (map && map->dso) { + BUG_ON(pthread_mutex_lock(&map->dso->lock) != 0); nsinfo__put(map->dso->nsinfo); map->dso->nsinfo = nsinfo__get(nsi); + pthread_mutex_unlock(&map->dso->lock); } return map; } else { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 43f47532696f..a504346feb05 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1774,6 +1774,7 @@ int dso__load(struct dso *dso, struct map *map) char newmapname[PATH_MAX]; const char *map_path = dso->long_name; + BUG_ON(pthread_mutex_lock(&dso->lock) != 0); perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0; if (perfmap) { if (dso->nsinfo && (dso__find_perf_map(newmapname, @@ -1783,7 +1784,6 @@ int dso__load(struct dso *dso, struct map *map) } nsinfo__mountns_enter(dso->nsinfo, &nsc); - BUG_ON(pthread_mutex_lock(&dso->lock) != 0); /* check again under the dso->lock */ if (dso__loaded(dso)) { -- 2.35.0.rc0.227.g00780c9af4-goog
| |