summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2026-06-06 21:48:13 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2026-06-10 15:23:53 -0300
commit4477dc01fcfc7f404772a67e0c1e056541ceb61d (patch)
treeecbdd9033b227a8e7d639a8dcd768bfab7d862ea /tools/perf
parenta9e900bc5c5914aca750afafa459363e575d3046 (diff)
downloadlwn-4477dc01fcfc7f404772a67e0c1e056541ceb61d.tar.gz
lwn-4477dc01fcfc7f404772a67e0c1e056541ceb61d.zip
perf sched: Bounds-check prio before test_bit() in timehist
timehist_skip_sample() reads prio from untrusted tracepoint data via perf_sample__intval(sample, "prev_prio") without bounds validation. A crafted perf.data with prev_prio >= MAX_PRIO (140) causes test_bit() to read past the end of the prio_bitmap, which is only MAX_PRIO bits. Add a prio >= 0 guard before the test_bit() call and skip out-of-range values (>= MAX_PRIO) that can never match the user's filter set. The original prio != -1 already let all negatives other than -1 through (after an undefined-behavior bitmap read); the new prio >= 0 guard preserves that pass-through behavior — negative means "no priority info", so the event is shown unfiltered — while fixing the OOB. Values >= MAX_PRIO are skipped because they cannot be represented in the filter bitmap. Fixes: 9b3a48bbe20d9692 ("perf sched timehist: Add --prio option") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Reviewed-by: Ian Rogers <irogers@google.com> Cc: Yang Jihong <yangjihong@bytedance.com> Assisted-by: Claude:claude-opus-4.6 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-sched.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 1ff01f03d2ad..caf05863a54e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2645,7 +2645,9 @@ static bool timehist_skip_sample(struct perf_sched *sched,
else if (evsel__name_is(sample->evsel, "sched:sched_switch"))
prio = perf_sample__intval(sample, "prev_prio");
- if (prio != -1 && !test_bit(prio, sched->prio_bitmap)) {
+ /* negative prio means no info; out-of-range prio can't match the filter */
+ if (prio >= 0 &&
+ (prio >= MAX_PRIO || !test_bit(prio, sched->prio_bitmap))) {
rc = true;
sched->skipped_samples++;
}