diff options
Diffstat (limited to 'util/nvmutil/nvmutil.c')
| -rw-r--r-- | util/nvmutil/nvmutil.c | 60 |
1 files changed, 19 insertions, 41 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index b718ac6e..df6167be 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -1133,16 +1133,8 @@ rhex(void) static size_t n = 0; static uint8_t rnum[12]; - if (use_prng) { - /* - * On very old Unix systems that - * lack /dev/random and /dev/urandom - */ + if (use_prng) return fallback_rand(); - } - - if (urandom_fd < 0) - err(ECANCELED, "Your operating system has no /dev/[u]random"); if (!n) { n = sizeof(rnum); @@ -1585,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) @@ -1596,43 +1592,25 @@ rw_file_once(int fd, uint8_t *mem, size_t len, read_again: rv = do_rw(fd, mem + rc, len - rc, off + rc, rw_type); - if (rv < 0 && errno == EINTR) { + if (rv < 0 && errno == EINTR) goto read_again; - } else if (rv < 0) { - errno = EIO; - 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; + if (rv < 0) return -1; - /* we will not tolerate your buggy libc */ - } - if ((size_t)rv > (len - rc) /* Prevent overflow */ - || rv == 0) { /* Prevent infinite 0-byte loop */ - if (rv == 0) { - /* - * 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; - } - errno = EIO; - return -1; - } + if ((size_t)rv > SSIZE_MAX /* theoretical buggy libc */ + || (size_t)rv > (len - rc))/* don't overflow */ + goto err_rw_file_once; + + if (rv != 0) + return rv; - return rv; + if (retries_on_zero++ < max_retries) + goto read_again; + +err_rw_file_once: + errno = EIO; + return -1; } static ssize_t |
