summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-03-13 15:15:10 +0000
committerLeah Rowe <leah@libreboot.org>2026-03-13 15:18:51 +0000
commit969e98c78dc8daf0fc6f93e607362596c140ee83 (patch)
treeb6dcae13b0d5889577676191cfdef33246918ae3
parent2b294eda37bebf01bf3eacb3f0fbf553aec48171 (diff)
util/nvmutil: stricter i/o arg checks
Signed-off-by: Leah Rowe <leah@libreboot.org>
-rw-r--r--util/nvmutil/nvmutil.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c
index 60a25eb0..266ba397 100644
--- a/util/nvmutil/nvmutil.c
+++ b/util/nvmutil/nvmutil.c
@@ -343,6 +343,8 @@ static ssize_t do_rw(int fd,
static ssize_t prw(int fd, void *mem, size_t nrw,
off_t off, int rw_type);
static off_t lseek_eintr(int fd, off_t off, int whence);
+static int io_args(int fd, void *mem, size_t nrw,
+ off_t off, int rw_type);
/*
* Error handling and cleanup
@@ -1569,8 +1571,7 @@ rw_file_exact(int fd, uint8_t *mem, size_t nrw,
ssize_t rv;
size_t rc;
- if (fd < 0 || !nrw || nrw > (size_t)SSIZE_MAX
- || (unsigned int)rw_type > IO_PWRITE) {
+ if (io_args(fd, mem, nrw, off, rw_type) == -1) {
errno = EIO;
return -1;
}
@@ -1597,13 +1598,7 @@ rw_file_once(int fd, uint8_t *mem, size_t nrw,
size_t retries_on_zero = 0;
size_t max_retries = 10;
- if (nrw != GBE_PART_SIZE &&
- nrw != NVM_SIZE &&
- nrw != NUM_RANDOM_BYTES)
- goto err_rw_file_once;
-
- if (fd < 0 || !nrw || nrw > (size_t)SSIZE_MAX
- || (unsigned int)rw_type > IO_PWRITE)
+ if (io_args(fd, mem, nrw, off, rw_type) == -1)
goto err_rw_file_once;
read_again:
@@ -1634,6 +1629,9 @@ static ssize_t
do_rw(int fd, uint8_t *mem,
size_t nrw, off_t off, int rw_type)
{
+ if (io_args(fd, mem, nrw, off, rw_type) == -1)
+ goto err_do_rw;
+
if (rw_type == IO_READ)
return read(fd, mem, nrw);
@@ -1643,6 +1641,7 @@ do_rw(int fd, uint8_t *mem,
if (rw_type == IO_PREAD || rw_type == IO_PWRITE)
return prw(fd, mem, nrw, off, rw_type);
+err_do_rw:
errno = EIO;
return -1;
}
@@ -1666,10 +1665,12 @@ prw(int fd, void *mem, size_t nrw,
int prw_type;
int flags;
+ if (io_args(fd, mem, nrw, off, rw_type) == -1)
+ goto err_prw;
+
prw_type = rw_type ^ IO_PREAD;
- if (fd < 0 || !nrw || nrw > (size_t)SSIZE_MAX
- || (unsigned int)prw_type > IO_WRITE)
+ if ((unsigned int)prw_type > IO_WRITE)
goto err_prw;
flags = fcntl(fd, F_GETFL);
@@ -1711,6 +1712,28 @@ err_prw:
return -1;
}
+static int
+io_args(int fd, void *mem, size_t nrw,
+ off_t off, int rw_type)
+{
+ if (nrw != GBE_PART_SIZE &&
+ nrw != NVM_SIZE &&
+ nrw != NUM_RANDOM_BYTES)
+ goto err_io_args;
+
+ if (fd < 0
+ || !nrw /* prevent zero read request */
+ || nrw > (size_t)SSIZE_MAX /* prevent overflow */
+ || (unsigned int)rw_type > IO_PWRITE)
+ goto err_io_args;
+
+ return 0;
+
+err_io_args:
+ errno = EIO;
+ return -1;
+}
+
static off_t
lseek_eintr(int fd, off_t off, int whence)
{