diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-13 03:44:22 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-13 03:44:22 +0000 |
| commit | 2d7d18d34e1dbe8c9b9557403f6211eab7d9ff13 (patch) | |
| tree | 02c5e65cf6260060c3f0ada538f2802cbbb7f5b2 /util | |
| parent | 76621fd5065c0623ef4e37b562dcf6d194843f30 (diff) | |
util/nvmutil: further tidy up rw_file_once
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util')
| -rw-r--r-- | util/nvmutil/nvmutil.c | 39 |
1 files changed, 11 insertions, 28 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index abe94904..df6167be 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -1577,6 +1577,10 @@ rw_file_exact(int fd, uint8_t *mem, size_t len, return rc; } +/* + * May not return all requested bytes (len). + * Use rw_file_exact for guaranteed length. + */ static ssize_t rw_file_once(int fd, uint8_t *mem, size_t len, off_t off, int rw_type, size_t rc) @@ -1584,48 +1588,27 @@ rw_file_once(int fd, uint8_t *mem, size_t len, ssize_t rv; size_t retries_on_zero = 0; size_t max_retries = 10; + read_again: rv = do_rw(fd, mem + rc, len - rc, off + rc, rw_type); if (rv < 0 && errno == EINTR) goto read_again; - if (rv < 0) { - errno = EIO; + if (rv < 0) return -1; - } - /* - * Theoretical bug: if a buggy libc returned - * a size larger than SSIZE_MAX, the cast may - * cause an overflow. Specifications guarantee - * this won't happen, but spec != implementation - */ - if ((size_t)rv > SSIZE_MAX) { - errno = EIO; - return -1; - /* we do not tolerate buggy libc */ - } + if ((size_t)rv > SSIZE_MAX /* theoretical buggy libc */ + || (size_t)rv > (len - rc))/* don't overflow */ + goto err_rw_file_once; - if (!((size_t)rv > (len - rc) /* don't overflow */ - || rv == 0)) + if (rv != 0) return rv; - /* Prevent infinite 0-byte loop */ - if (rv != 0) { - errno = EIO; - return -1; - } - /* - * Fault tolerance against infinite - * zero-byte loop: re-try a finite - * number of times. This mitigates - * otherwise OK but slow filesystems - * e.g. NFS or slow media. - */ if (retries_on_zero++ < max_retries) goto read_again; +err_rw_file_once: errno = EIO; return -1; } |
