diff options
| author | Ian Rogers <irogers@google.com> | 2026-07-22 21:59:47 -0700 |
|---|---|---|
| committer | Namhyung Kim <namhyung@kernel.org> | 2026-07-27 17:30:33 -0700 |
| commit | bd86119c3ee6ed7b8fc9be8298fe49f1a5355a46 (patch) | |
| tree | 5a6edbd96c6bfa9dc441ccfb74032b036b8278b7 | |
| parent | ae89153d5e50d22e04a084829f74dc5a9ae6eb6d (diff) | |
| download | linux-next-bd86119c3ee6ed7b8fc9be8298fe49f1a5355a46.tar.gz linux-next-bd86119c3ee6ed7b8fc9be8298fe49f1a5355a46.zip | |
perf ui hists: Fix dso_filter reference leak and exit zoom cleanup
In hists_browser__zoom_map(), the active dso is assigned as a raw
pointer to hists->dso_filter without acquiring a reference using
dso__get(). This creates a potential use-after-free defect if the
underlying dso is released while the filter remains active.
Fix it by properly acquiring a reference via dso__get() when assigning
the filter, and releasing it with dso__put() when clearing it.
Additionally, since the browser stack relies on pstack__new() and deletes
it completely upon exiting, we must fully reset the persistent hists
structure by un-eliding columns and recalculating histogram filter
states for dso, thread, and symbols upon exit to guarantee immaculate,
uncorrupted state across browser tab switching.
Closes: https://lore.kernel.org/linux-perf-users/20260709170834.52F1A1F000E9@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
| -rw-r--r-- | tools/perf/ui/browsers/hists.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 684df550ba49..39d83f15f23c 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2651,13 +2651,14 @@ static int hists_browser__zoom_map(struct hist_browser *browser, struct map *map if (browser->hists->dso_filter) { pstack__remove(browser->pstack, &browser->hists->dso_filter); perf_hpp__set_elide(HISTC_DSO, false); + dso__put((struct dso *)browser->hists->dso_filter); browser->hists->dso_filter = NULL; ui_helpline__pop(); } else { struct dso *dso = map__dso(map); ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"", __map__is_kernel(map) ? "the Kernel" : dso__short_name(dso)); - browser->hists->dso_filter = dso; + browser->hists->dso_filter = dso__get(dso); perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); } @@ -3025,7 +3026,7 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h struct branch_info *bi = NULL; #define MAX_OPTIONS 32 char *options[MAX_OPTIONS]; - struct popup_action actions[MAX_OPTIONS]; + struct popup_action actions[MAX_OPTIONS], hotkey_act; int nr_options = 0; int key = -1; char buf[128]; @@ -3498,6 +3499,13 @@ skip_scripting: out_free_stack: pstack__delete(browser->pstack); free_popup_actions(actions, MAX_OPTIONS); + thread__zput(hists->thread_filter); + dso__put((struct dso *)hists->dso_filter); + hists->dso_filter = NULL; + perf_hpp__set_elide(HISTC_DSO, false); + perf_hpp__set_elide(HISTC_THREAD, false); + hists__filter_by_dso(hists); + hists__filter_by_thread(hists); out: hist_browser__delete(browser); free_popup_options(options, MAX_OPTIONS); |
