diff options
author | delphij <delphij@FreeBSD.org> | 2014-12-10 08:18:22 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2014-12-10 08:18:22 +0000 |
commit | 6094244ca488711a1bca11cddcbc65b6a4245e71 (patch) | |
tree | d1914d5635a85d8c0dab209b492d8ffb0265c9e7 /lib/libc | |
parent | 8f2224905ca7c266b9833bbb440802a0132abe33 (diff) | |
download | FreeBSD-src-6094244ca488711a1bca11cddcbc65b6a4245e71.zip FreeBSD-src-6094244ca488711a1bca11cddcbc65b6a4245e71.tar.gz |
In r268924 __fflush was modified so that when write(2) was not successful,
_p and _w are adjusted to account for the partial write (if any).
However, _p and _w should not be unconditionally adjusted and should only
be changed when we actually wrote some bytes, or the accumulated accounting
error will eventually result in a heap buffer overflow.
Reported by: adrian and alfred (Norse Corporation)
Security: FreeBSD-SA-14:27.stdio
Security: CVE-2014-8611
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdio/fflush.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index ef9b45b..123167a 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -124,11 +124,13 @@ __sflush(FILE *fp) t = _swrite(fp, (char *)p, n); if (t <= 0) { /* Reset _p and _w. */ - if (p > fp->_p) /* Some was written. */ + if (p > fp->_p) { + /* Some was written. */ memmove(fp->_p, p, n); - fp->_p += n; - if ((fp->_flags & (__SLBF | __SNBF)) == 0) - fp->_w -= n; + fp->_p += n; + if ((fp->_flags & (__SLBF | __SNBF)) == 0) + fp->_w -= n; + } fp->_flags |= __SERR; return (EOF); } |