summaryrefslogtreecommitdiff
path: root/util/nvmutil/nvmutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/nvmutil/nvmutil.c')
-rw-r--r--util/nvmutil/nvmutil.c60
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