mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-22 05:00:08 +02:00
util/nvmutil: further tidy up rw_file_once
Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
+11
-28
@@ -1577,6 +1577,10 @@ rw_file_exact(int fd, uint8_t *mem, size_t len,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* May not return all requested bytes (len).
|
||||||
|
* Use rw_file_exact for guaranteed length.
|
||||||
|
*/
|
||||||
static ssize_t
|
static ssize_t
|
||||||
rw_file_once(int fd, uint8_t *mem, size_t len,
|
rw_file_once(int fd, uint8_t *mem, size_t len,
|
||||||
off_t off, int rw_type, size_t rc)
|
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;
|
ssize_t rv;
|
||||||
size_t retries_on_zero = 0;
|
size_t retries_on_zero = 0;
|
||||||
size_t max_retries = 10;
|
size_t max_retries = 10;
|
||||||
|
|
||||||
read_again:
|
read_again:
|
||||||
rv = do_rw(fd, mem + rc, len - rc, off + rc, rw_type);
|
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;
|
goto read_again;
|
||||||
|
|
||||||
if (rv < 0) {
|
if (rv < 0)
|
||||||
errno = EIO;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if ((size_t)rv > SSIZE_MAX /* theoretical buggy libc */
|
||||||
* Theoretical bug: if a buggy libc returned
|
|| (size_t)rv > (len - rc))/* don't overflow */
|
||||||
* a size larger than SSIZE_MAX, the cast may
|
goto err_rw_file_once;
|
||||||
* 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 > (len - rc) /* don't overflow */
|
if (rv != 0)
|
||||||
|| rv == 0))
|
|
||||||
return rv;
|
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)
|
if (retries_on_zero++ < max_retries)
|
||||||
goto read_again;
|
goto read_again;
|
||||||
|
|
||||||
|
err_rw_file_once:
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user