summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-10 10:14:25 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-10 10:14:25 +0000
commitb56cfbcc54d1e9c8b5e9977d9c70bdc3c8db3038 (patch)
tree9e2b7f5e8e40c99a9f62f4bbbfd4827ae40dd73b
parent19ee28161e6e3ddd2185916d45271b79b04d4bf6 (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.c16
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;