[PATCH v3 4/4] perf hists browser: Increase MAX_OPTIONS to prevent stack buffer overflow

From: Ian Rogers

Date: Thu Jul 09 2026 - 12:54:12 EST


In evsel__hists_browse(), the 'options' and 'actions' arrays are
statically allocated on the stack with a size of MAX_OPTIONS
(16). Further down, the function sequentially calls several
add_*_opt() functions, which increment nr_options without bounds
checking.

Depending on the context (e.g., branch mode, scripting, annotations),
the sum of added options can theoretically exceed 16 (potentially
reaching up to ~19). This could lead to a stack buffer overflow.

Increase MAX_OPTIONS to 32 to accommodate the maximum possible number
of options without risking an overflow.

Sashiko also caught an existing bug where uninitialized memory could
be read on an error path. Move the memsets to avoid this.

Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/linux-perf-users/20260708235834.3FB771F00A3A@xxxxxxxxxxxxxxx/
Fixes: f2b487db45f2 ("perf hists browser: Fix possible memory leak")
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/ui/browsers/hists.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index c032068568d5..3bd84a35df41 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -3002,7 +3002,7 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h
struct hists *hists = evsel__hists(evsel);
struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env);
struct branch_info *bi = NULL;
-#define MAX_OPTIONS 16
+#define MAX_OPTIONS 32
char *options[MAX_OPTIONS];
struct popup_action actions[MAX_OPTIONS];
int nr_options = 0;
@@ -3063,15 +3063,15 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h
browser->min_pcnt = min_pcnt;
hist_browser__update_nr_entries(browser);

+ memset(options, 0, sizeof(options));
+ memset(actions, 0, sizeof(actions));
+
browser->pstack = pstack__new(3);
if (browser->pstack == NULL)
goto out;

ui_helpline__push(helpline);

- memset(options, 0, sizeof(options));
- memset(actions, 0, sizeof(actions));
-
if (symbol_conf.col_width_list_str)
perf_hpp__set_user_width(symbol_conf.col_width_list_str);

--
2.55.0.795.g602f6c329a-goog