summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/stdio.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-08-31 12:55:22 +0000
committerache <ache@FreeBSD.org>2001-08-31 12:55:22 +0000
commitae7b8fc7f6b359ec0633a545f7f08668243d2336 (patch)
tree652a448f600a36d10c845c506e6edf40933a4ebd /lib/libc/stdio/stdio.c
parentc98f3a3f5e4b253474b2fcc952dc2e9c25725a0e (diff)
downloadFreeBSD-src-ae7b8fc7f6b359ec0633a545f7f08668243d2336.zip
FreeBSD-src-ae7b8fc7f6b359ec0633a545f7f08668243d2336.tar.gz
Detect fp->_offset overflow on read
Use errno to catch negative seek with -1 offset
Diffstat (limited to 'lib/libc/stdio/stdio.c')
-rw-r--r--lib/libc/stdio/stdio.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c
index 75f59c4..46dd2df 100644
--- a/lib/libc/stdio/stdio.c
+++ b/lib/libc/stdio/stdio.c
@@ -45,8 +45,9 @@ static const char rcsid[] =
#include "namespace.h"
#include <errno.h>
#include <fcntl.h>
-#include <unistd.h>
+#include <limits.h>
#include <stdio.h>
+#include <unistd.h>
#include "un-namespace.h"
#include "local.h"
@@ -65,10 +66,19 @@ __sread(cookie, buf, n)
ret = _read(fp->_file, buf, (size_t)n);
/* if the read succeeded, update the current offset */
- if (ret >= 0)
- fp->_offset += ret;
- else
- fp->_flags &= ~__SOFF; /* paranoia */
+ if (ret >= 0) {
+ if (fp->_flags & __SOFF) {
+ if (fp->_offset > OFF_MAX - ret) {
+ errno = EOVERFLOW;
+ ret = -1;
+ } else {
+ fp->_offset += ret;
+ return (ret);
+ }
+ } else
+ return (ret);
+ }
+ fp->_flags &= ~__SOFF;
return (ret);
}
@@ -94,20 +104,24 @@ __sseek(cookie, offset, whence)
{
register FILE *fp = cookie;
register off_t ret;
+ int serrno, errret;
+ serrno = errno;
+ errno = 0;
ret = lseek(fp->_file, (off_t)offset, whence);
+ errret = errno;
+ if (errno == 0)
+ errno = serrno;
/*
* Disallow negative seeks per POSIX.
* It is needed here to help upper level caller
* (fseek) in the cases it can't detect.
*/
if (ret < 0) {
- if (ret != -1) {
- /* Resulting seek is negative! */
- ret = -1;
+ if (errret == 0)
errno = EINVAL;
- }
fp->_flags &= ~__SOFF;
+ ret = -1;
} else {
fp->_flags |= __SOFF;
fp->_offset = ret;
OpenPOWER on IntegriCloud