diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-08 03:03:55 +0300 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2026-06-11 00:56:01 +0300 |
| commit | 52b1f9678499b13b7aeb0186d9c6f486c043283f (patch) | |
| tree | 1a15e434e86799deabb08ec36c8a3ee63fe571ac | |
| parent | 33035f7dd4e49f3f117e70c5e36c8c1ae88d37f2 (diff) | |
| download | linux-52b1f9678499b13b7aeb0186d9c6f486c043283f.tar.xz | |
tools lib api: Fix missing null termination in filename__read_int/ull()
filename__read_int() passes a stack buffer to read() using the full
sizeof(line) and then hands it to atoi() without null-terminating.
If a sysfs file fills the 64-byte buffer exactly, atoi() reads past
the array into uninitialized stack memory.
filename__read_ull_base() has the same issue with strtoull().
Fix both by reading sizeof(line) - 1 bytes and explicitly
null-terminating after a successful read.
Fixes: 3a351127cbc682c3 ("tools lib fs: Adopt filename__read_int from tools/perf/")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/lib/api/fs/fs.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index edec23406dbc..3cc302d4c47b 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c @@ -294,11 +294,14 @@ int filename__read_int(const char *filename, int *value) { char line[64]; int fd = open(filename, O_RDONLY), err = -1; + ssize_t n; if (fd < 0) return -errno; - if (read(fd, line, sizeof(line)) > 0) { + n = read(fd, line, sizeof(line) - 1); + if (n > 0) { + line[n] = '\0'; *value = atoi(line); err = 0; } @@ -312,11 +315,14 @@ static int filename__read_ull_base(const char *filename, { char line[64]; int fd = open(filename, O_RDONLY), err = -1; + ssize_t n; if (fd < 0) return -errno; - if (read(fd, line, sizeof(line)) > 0) { + n = read(fd, line, sizeof(line) - 1); + if (n > 0) { + line[n] = '\0'; *value = strtoull(line, NULL, base); if (*value != ULLONG_MAX) err = 0; |
