mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-16 23:08:49 +02:00
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 <leah@libreboot.org>
This commit is contained in:
+36
-18
@@ -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);
|
off_t off, int rw_type, size_t rc, int loop_eagain);
|
||||||
static ssize_t prw(int fd, void *mem, size_t nrw,
|
static ssize_t prw(int fd, void *mem, size_t nrw,
|
||||||
off_t off, int rw_type, int loop_eagain);
|
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,
|
static off_t lseek_eintr(int fd, off_t off,
|
||||||
int whence, int loop_eagain);
|
int whence, int loop_eagain);
|
||||||
static int err_eagain(int loop_eagain);
|
static int err_eagain(int loop_eagain);
|
||||||
@@ -1709,7 +1709,7 @@ try_rw_again:
|
|||||||
|| errno == err_eagain(loop_eagain)))
|
|| errno == err_eagain(loop_eagain)))
|
||||||
goto try_rw_again;
|
goto try_rw_again;
|
||||||
|
|
||||||
return rw_over_ssize_max(r);
|
return rw_over_nrw(r, nrw);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = fcntl(fd, F_GETFL);
|
flags = fcntl(fd, F_GETFL);
|
||||||
@@ -1737,7 +1737,7 @@ try_rw_again:
|
|||||||
else if (rw_type == IO_PWRITE)
|
else if (rw_type == IO_PWRITE)
|
||||||
r = write(fd, mem, nrw);
|
r = write(fd, mem, nrw);
|
||||||
|
|
||||||
r = rw_over_ssize_max(r);
|
r = rw_over_nrw(r, nrw);
|
||||||
} while (r == -1 && (errno == EINTR
|
} while (r == -1 && (errno == EINTR
|
||||||
|| errno == err_eagain(loop_eagain)));
|
|| errno == err_eagain(loop_eagain)));
|
||||||
|
|
||||||
@@ -1750,35 +1750,53 @@ try_rw_again:
|
|||||||
}
|
}
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
return rw_over_ssize_max(r);
|
return rw_over_nrw(r, nrw);
|
||||||
|
|
||||||
err_prw:
|
err_prw:
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Theoretical buggy libc
|
* POSIX can say whatever it wants.
|
||||||
* check. Extremely academic.
|
* specification != implementation
|
||||||
*
|
|
||||||
* Specifications never
|
|
||||||
* allow this return value
|
|
||||||
* to exceed SSIZE_MAX, but
|
|
||||||
* spec != implementation
|
|
||||||
*
|
|
||||||
* Check this after using
|
|
||||||
* [p]read() or [p]write()
|
|
||||||
*/
|
*/
|
||||||
static int
|
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) {
|
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;
|
return r;
|
||||||
|
|
||||||
|
err_rw_over_nrw:
|
||||||
|
|
||||||
|
errno = EIO;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t
|
static off_t
|
||||||
|
|||||||
Reference in New Issue
Block a user