From 69ff774ad3a4823bc02fd4d34c97525a32fe7dd4 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sat, 14 Mar 2026 00:12:10 +0000 Subject: util/nvmutil: extra overflow check in prw compliant posix systems should never meet this check, but i put it here. spec != implementation Signed-off-by: Leah Rowe --- util/nvmutil/nvmutil.c | 54 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'util') diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index 25e784d9..62c5ee2a 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -335,7 +335,7 @@ static ssize_t rw_file_once(int fd, u8 *mem, size_t len, off_t off, int rw_type, size_t rc, int loop_eagain); static ssize_t prw(int fd, void *mem, size_t nrw, off_t off, int rw_type, int loop_eagain); -static int rw_over_ssize_max(ssize_t r); +static int rw_over_nrw(ssize_t r, size_t nrw); static off_t lseek_eintr(int fd, off_t off, int whence, int loop_eagain); static int err_eagain(int loop_eagain); @@ -1709,7 +1709,7 @@ try_rw_again: || errno == err_eagain(loop_eagain))) goto try_rw_again; - return rw_over_ssize_max(r); + return rw_over_nrw(r, nrw); } flags = fcntl(fd, F_GETFL); @@ -1737,7 +1737,7 @@ try_rw_again: else if (rw_type == IO_PWRITE) r = write(fd, mem, nrw); - r = rw_over_ssize_max(r); + r = rw_over_nrw(r, nrw); } while (r == -1 && (errno == EINTR || errno == err_eagain(loop_eagain))); @@ -1750,35 +1750,53 @@ try_rw_again: } errno = saved_errno; - return rw_over_ssize_max(r); + return rw_over_nrw(r, nrw); err_prw: errno = EIO; return -1; } - /* - * Theoretical buggy libc - * check. Extremely academic. - * - * Specifications never - * allow this return value - * to exceed SSIZE_MAX, but - * spec != implementation - * - * Check this after using - * [p]read() or [p]write() + * POSIX can say whatever it wants. + * specification != implementation */ static int -rw_over_ssize_max(ssize_t r) +rw_over_nrw(ssize_t r, size_t nrw) { + if (r == -1) + return r; + if ((size_t)r > SSIZE_MAX) { - errno = EIO; - return -1; + /* + * Theoretical buggy libc + * check. Extremely academic. + * + * Specifications never + * allow this return value + * to exceed SSIZE_MAX, but + * spec != implementation + * + * Check this after using + * [p]read() or [p]write() + */ + goto err_rw_over_nrw; } + /* + * Theoretical buggy libc: + * Should never return a number of + * bytes above the requested length. + */ + if ((size_t)r > nrw) + goto err_rw_over_nrw; + return r; + +err_rw_over_nrw: + + errno = EIO; + return -1; } static off_t -- cgit v1.2.1