diff options
author | ache <ache@FreeBSD.org> | 2001-08-15 02:07:47 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2001-08-15 02:07:47 +0000 |
commit | 9d7273169f482f1f74606c9f559ecc986f668088 (patch) | |
tree | c651de630103d0b82ee727fa499a87af0697e6f6 /lib/libc/stdio/fseek.c | |
parent | 679dd2c9f81d6f490f3db2613cb62f20c7cf93ab (diff) | |
download | FreeBSD-src-9d7273169f482f1f74606c9f559ecc986f668088.zip FreeBSD-src-9d7273169f482f1f74606c9f559ecc986f668088.tar.gz |
1) Disallow negative seek as POSIX require for fseek{o} (but not for lseek):
"[EINVAL] ... The resulting file-position indicator would be set to a
negative value."
Moreover, in real life negative seek in stdio cause EOF indicator cleared
and not set again forever even if EOF returned.
2) Catch few possible off_t overflows.
Reviewed by: arch discussion
Diffstat (limited to 'lib/libc/stdio/fseek.c')
-rw-r--r-- | lib/libc/stdio/fseek.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index b434350..d311f7a 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -132,12 +132,26 @@ _fseeko(fp, offset, whence) } else if (fp->_flags & __SWR && fp->_p != NULL) curoff += fp->_p - fp->_bf._base; + if (offset > 0 && offset + (off_t)curoff < 0) { + errno = EOVERFLOW; + return (EOF); + } offset += curoff; + /* Disallow negative seeks per POSIX */ + if (offset < 0) { + errno = EINVAL; + return (EOF); + } whence = SEEK_SET; havepos = 1; break; case SEEK_SET: + /* Disallow negative seeks per POSIX */ + if (offset < 0) { + errno = EINVAL; + return (EOF); + } case SEEK_END: curoff = 0; /* XXX just to keep gcc quiet */ havepos = 0; @@ -180,7 +194,16 @@ _fseeko(fp, offset, whence) else { if (_fstat(fp->_file, &st)) goto dumb; + if (offset > 0 && st.st_size + offset < 0) { + errno = EOVERFLOW; + return (EOF); + } target = st.st_size + offset; + /* Disallow negative seeks per POSIX */ + if ((off_t)target < 0) { + errno = EINVAL; + return (EOF); + } } if (!havepos) { |