]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf hwmon: Fix off-by-one null termination on sysfs reads
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Jun 2026 01:38:26 +0000 (22:38 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 10 Jun 2026 21:56:01 +0000 (18:56 -0300)
Three functions read sysfs files into fixed-size stack buffers using
the full buffer size, then null-terminate at buf[read_len].  If the
read fills the buffer exactly, read_len equals sizeof(buf) and the
null byte writes one past the array, corrupting an adjacent stack
variable.

Fix all three by reading sizeof(buf) - 1 bytes, reserving space for
the null terminator:

  - hwmon_pmu__read_events(): buf[128]
  - hwmon_pmu__describe_items(): buf[64]
  - evsel__hwmon_pmu_read(): buf[32]

Fixes: 53cc0b351ec99278 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/hwmon_pmu.c

index dbf6a71af47f9a42d4c5e4f86c10635efcb0e83f..d895cd74f2a05f9dfefd5e8f93471fc69dab7a1a 100644 (file)
@@ -289,7 +289,7 @@ static int hwmon_pmu__read_events(struct hwmon_pmu *pmu)
                        if (fd < 0)
                                continue;
 
-                       read_len = read(fd, buf, sizeof(buf));
+                       read_len = read(fd, buf, sizeof(buf) - 1);
 
                        while (read_len > 0 && buf[read_len - 1] == '\n')
                                read_len--;
@@ -432,7 +432,7 @@ static size_t hwmon_pmu__describe_items(struct hwmon_pmu *hwm, char *out_buf, si
                        is_alarm ? "_alarm" : "");
                fd = openat(dir, buf, O_RDONLY);
                if (fd > 0) {
-                       ssize_t read_len = read(fd, buf, sizeof(buf));
+                       ssize_t read_len = read(fd, buf, sizeof(buf) - 1);
 
                        while (read_len > 0 && buf[read_len - 1] == '\n')
                                read_len--;
@@ -816,7 +816,7 @@ int evsel__hwmon_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread)
 
        count = perf_counts(evsel->counts, cpu_map_idx, thread);
        fd = FD(evsel, cpu_map_idx, thread);
-       len = pread(fd, buf, sizeof(buf), 0);
+       len = pread(fd, buf, sizeof(buf) - 1, 0);
        if (len <= 0) {
                count->lost++;
                return -EINVAL;