mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-27 03:11:52 +01:00
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
This commit is contained in:
parent
ba8140a6f6
commit
d9e3eff33a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81666
@ -180,18 +180,12 @@ is not a seekable stream.
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa whence
|
||||
argument to
|
||||
.Fn fseek
|
||||
was not
|
||||
.Dv SEEK_SET ,
|
||||
.Dv SEEK_END ,
|
||||
or
|
||||
.Dv SEEK_CUR .
|
||||
argument is invalid.
|
||||
The resulting file-position
|
||||
indicator would be set to a negative value.
|
||||
.It Bq Er EOVERFLOW
|
||||
For
|
||||
.Fn ftell ,
|
||||
the resulting file offset would be a value which
|
||||
cannot be represented correctly in an object of type long.
|
||||
The resulting file offset would be a value which
|
||||
cannot be represented correctly in an object of type requested.
|
||||
.El
|
||||
.Pp
|
||||
The functions
|
||||
|
@ -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) {
|
||||
|
@ -43,6 +43,7 @@ static const char rcsid[] =
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@ -94,10 +95,24 @@ __sseek(cookie, offset, whence)
|
||||
register FILE *fp = cookie;
|
||||
register off_t ret;
|
||||
|
||||
/*
|
||||
* Disallow negative seeks per POSIX.
|
||||
* It is needed here to help upper level caller
|
||||
* (fseek) in the cases it can't detect.
|
||||
*/
|
||||
if (whence == SEEK_SET && (off_t)offset < 0) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
ret = lseek(fp->_file, (off_t)offset, whence);
|
||||
if (ret == -1)
|
||||
if (ret < 0) {
|
||||
if (ret != -1) {
|
||||
/* Resulting seek is negative! */
|
||||
ret = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
fp->_flags &= ~__SOFF;
|
||||
else {
|
||||
} else {
|
||||
fp->_flags |= __SOFF;
|
||||
fp->_offset = ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user