From 7389a9228b0cfcdcf7542b267048e8adc9955a0f Mon Sep 17 00:00:00 2001 From: Lucas Holt Date: Wed, 8 Nov 2023 09:12:52 -0500 Subject: [PATCH] For line-buffered streams the __sflush() function did not correctly update the FILE object's write space member when the write(2) system call returns an error. Depending on the nature of an application that calls libc's stdio functions and the presence of errors returned from the write(2) system call (or an overridden stdio write routine) a heap buffer overfly may occur. Such overflows may lead to data corruption or the execution of arbitrary code at the privilege level of the calling program. Obtained from: FreeBSD --- lib/libc/stdio/fflush.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index 675e18c570..7517aa7dd0 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -105,10 +105,10 @@ int __sflush(FILE *fp) { unsigned char *p; - int n, t; + int n, f, t; - t = fp->_flags; - if ((t & __SWR) == 0) + f = fp->_flags; + if ((f & __SWR) == 0) return (0); if ((p = fp->_bf._base) == NULL) @@ -121,19 +121,18 @@ __sflush(FILE *fp) * exchange buffering (via setvbuf) in user write function. */ fp->_p = p; - fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + fp->_w = f & (__SLBF|__SNBF) ? 0 : fp->_bf._size; for (; n > 0; n -= t, p += t) { t = _swrite(fp, (char *)p, n); if (t <= 0) { - /* Reset _p and _w. */ - if (p > fp->_p) { + if (p > fp->_p) /* Some was written. */ memmove(fp->_p, p, n); - fp->_p += n; - if ((fp->_flags & (__SLBF | __SNBF)) == 0) - fp->_w -= n; - } + /* Reset _p and _w. */ + fp->_p += n; + if ((fp->_flags & __SNBF) == 0) + fp->_w -= n; fp->_flags |= __SERR; return (EOF); }