mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Fix fwrite() reading beyond end of buffer in error path
Partially revert commits2b766585f9
andde2fd463b1
, which were intended to fix BZ#11741 but caused another, likely worse bug, namely that fwrite() and fputs() could, in an error path, read data beyond the end of the specified buffer, and potentially even write this data to the file. Fix BZ#11741 properly by checking the return value from _IO_padn() in stdio-common/vfprintf.c.
This commit is contained in:
committed by
Siddhesh Poyarekar
parent
75b4202ab0
commit
3d110c7c6e
@ -1245,13 +1245,12 @@ _IO_new_file_write (f, data, n)
|
||||
_IO_ssize_t n;
|
||||
{
|
||||
_IO_ssize_t to_do = n;
|
||||
_IO_ssize_t count = 0;
|
||||
while (to_do > 0)
|
||||
{
|
||||
count = (__builtin_expect (f->_flags2
|
||||
& _IO_FLAGS2_NOTCANCEL, 0)
|
||||
? write_not_cancel (f->_fileno, data, to_do)
|
||||
: write (f->_fileno, data, to_do));
|
||||
_IO_ssize_t count = (__builtin_expect (f->_flags2
|
||||
& _IO_FLAGS2_NOTCANCEL, 0)
|
||||
? write_not_cancel (f->_fileno, data, to_do)
|
||||
: write (f->_fileno, data, to_do));
|
||||
if (count < 0)
|
||||
{
|
||||
f->_flags |= _IO_ERR_SEEN;
|
||||
@ -1263,7 +1262,7 @@ _IO_new_file_write (f, data, n)
|
||||
n -= to_do;
|
||||
if (f->_offset >= 0)
|
||||
f->_offset += n;
|
||||
return count < 0 ? count : n;
|
||||
return n;
|
||||
}
|
||||
|
||||
_IO_size_t
|
||||
@ -1323,13 +1322,11 @@ _IO_new_file_xsputn (f, data, n)
|
||||
_IO_size_t block_size, do_write;
|
||||
/* Next flush the (full) buffer. */
|
||||
if (_IO_OVERFLOW (f, EOF) == EOF)
|
||||
/* If nothing else has to be written or nothing has been written, we
|
||||
must not signal the caller that the call was even partially
|
||||
successful. */
|
||||
return (to_do == 0 || to_do == n) ? EOF : n - to_do;
|
||||
/* If nothing else has to be written we must not signal the
|
||||
caller that everything has been written. */
|
||||
return to_do == 0 ? EOF : n - to_do;
|
||||
|
||||
/* Try to maintain alignment: write a whole number of blocks.
|
||||
dont_write is what gets left over. */
|
||||
/* Try to maintain alignment: write a whole number of blocks. */
|
||||
block_size = f->_IO_buf_end - f->_IO_buf_base;
|
||||
do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
|
||||
|
||||
|
Reference in New Issue
Block a user