diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-07 21:03:13 -0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-10 18:56:01 -0300 |
| commit | 33035f7dd4e49f3f117e70c5e36c8c1ae88d37f2 (patch) | |
| tree | d9c554c95a0f2c6c95b2ce689419ab6fb978877b /tools/perf | |
| parent | 836455e6dbd34eb3d12eeab5e2d2b9a7f1512459 (diff) | |
| download | lwn-33035f7dd4e49f3f117e70c5e36c8c1ae88d37f2.tar.gz lwn-33035f7dd4e49f3f117e70c5e36c8c1ae88d37f2.zip | |
perf pmu: Fix perf_pmu__parse_scale/unit() OOB access on empty sysfs file
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@kernel.org>
Cc: Stephane Eranian <eranian@google.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/util/pmu.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f588cce60194..a550f030b85d 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); |
