[PATCH 02/23] perf pmu: Fix perf_pmu__parse_scale/unit() OOB access on empty sysfs file

From: Arnaldo Carvalho de Melo

Date: Wed Jun 10 2026 - 15:55:20 EST


From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

perf_pmu__parse_scale() reads a PMU scale file then accesses
scale[sret - 1] to strip a trailing newline. Only sret < 0 is
guarded, so an empty file (sret == 0) causes scale[-1] — a stack
buffer underflow that reads and potentially writes out of bounds.

perf_pmu__parse_unit() has the same pattern: alias->unit[sret - 1]
with sret == 0 accesses the byte before the struct member, which
may corrupt the adjacent pmu_name pointer field.

Change both guards from sret < 0 to sret <= 0 so that empty files
are treated as read errors.

Fixes: 410136f5dd96b601 ("tools/perf/stat: Add event unit and scale support")
Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
Cc: Stephane Eranian <eranian@xxxxxxxxxx>
Assisted-by: Claude Opus 4.6 <noreply@xxxxxxxxxxxxx>
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/util/pmu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 50f54674430e6206..4ddccc863727d6ca 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -314,7 +314,7 @@ static int perf_pmu__parse_scale(struct perf_pmu *pmu, struct perf_pmu_alias *al
goto error;

sret = read(fd, scale, sizeof(scale)-1);
- if (sret < 0)
+ if (sret <= 0)
goto error;

if (scale[sret - 1] == '\n')
@@ -346,7 +346,7 @@ static int perf_pmu__parse_unit(struct perf_pmu *pmu, struct perf_pmu_alias *ali
return -1;

sret = read(fd, alias->unit, UNIT_MAX_LEN);
- if (sret < 0)
+ if (sret <= 0)
goto error;

close(fd);
--
2.54.0