From 05272960abb77e1c53239683d4adc6077e5549ea Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 15 Dec 2016 12:06:04 -0500 Subject: [PATCH] 2016-12-15 Giuseppe Musumeci __sinit initialises some common file descriptors as line buffered and relies on the first users of such FDs to call __smakebuf_r. If __smakebuf_r realises there's no space for a buffer (malloc returns NULL), it makes them unbuffered. However, while setting the __SNBF bit, it doesn't clear the __SLBF bit in the flags. Depending on the order in which functions check buffering flags in the FD, sometime they assume it's line buffered (e.g. __sfvwrite_r), trashing application memory that's not really been allocated to them. This patch solves the problem by clearing the unbuffered/line buffered flag when setting the line buffered/unbuffered flag. --- newlib/libc/stdio/makebuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/newlib/libc/stdio/makebuf.c b/newlib/libc/stdio/makebuf.c index c592578b8..ab20a0838 100644 --- a/newlib/libc/stdio/makebuf.c +++ b/newlib/libc/stdio/makebuf.c @@ -55,7 +55,7 @@ _DEFUN(__smakebuf_r, (ptr, fp), { if (!(fp->_flags & __SSTR)) { - fp->_flags |= __SNBF; + fp->_flags = (fp->_flags & ~__SLBF) | __SNBF; fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; } @@ -67,7 +67,7 @@ _DEFUN(__smakebuf_r, (ptr, fp), fp->_bf._base = fp->_p = (unsigned char *) p; fp->_bf._size = size; if (couldbetty && _isatty_r (ptr, fp->_file)) - fp->_flags |= __SLBF; + fp->_flags = (fp->_flags & ~__SNBF) | __SLBF; fp->_flags |= flags; } }