diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-10 10:14:25 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-10 10:14:25 +0000 |
| commit | b56cfbcc54d1e9c8b5e9977d9c70bdc3c8db3038 (patch) | |
| tree | 9e2b7f5e8e40c99a9f62f4bbbfd4827ae40dd73b | |
| parent | 19ee28161e6e3ddd2185916d45271b79b04d4bf6 (diff) | |
util/nvmutil: fix buffer overread in prw()
edge case scenario, unlikely to actually trigger.
now impossible to trigger.
Signed-off-by: Leah Rowe <leah@libreboot.org>
| -rw-r--r-- | util/nvmutil/nvmutil.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index 34b48504..f6174352 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -1319,7 +1319,7 @@ rw_file_exact(int fd, uint8_t *mem, size_t len, off_t off, int rw_type, const char *path, const char *rw_type_str) { - ssize_t rval = -1; + ssize_t rval = 0; size_t rc = 0; if (fd < 0) @@ -1331,7 +1331,7 @@ rw_file_exact(int fd, uint8_t *mem, size_t len, "%s: %s: Requested length (%lu) exceeds SSIZE_MAX (%zd)", path, rw_type_str, len, SSIZE_MAX); - for (rc = 0; rc < len; rc += rval) { + while (rc < len) { if (rw_type == PSCHREIB) rval = prw(fd, mem + rc, len - rc, off + rc, rw_type, path); @@ -1346,14 +1346,20 @@ rw_file_exact(int fd, uint8_t *mem, size_t len, err(EIO, "%s: %s: Unsupported rw_type", path, rw_type_str); - if (rval > -1) { - if (!rval) /* prevent infinite loop */ + if (rval >= 0) { + if (rval == 0) err(EIO, "%s: %s: 0-byte return", path, rw_type_str); + + if ((size_t)rval > (len - rc)) + err(EIO, "%s: %s: Buffer overread trap", + path, rw_type_str); + + rc += (size_t)rval; continue; } - if (errno != EINTR || rval < -1) + if (errno != EINTR) err(EIO, "%s: %s", path, rw_type_str); errno = 0; |
