mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
Commit a601b74d31
aka glibc-2.23~693
("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
when _G_HAVE_MMAP is turned off.") introduced a regression:
_IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all
files, including legacy standard files which are small statically
allocated objects that do not have wide buffers and the _mode member,
causing memory corruption.
Another memory corruption in _IO_unbuffer_all happens when -1
is assigned to the _mode member of legacy standard files that
do not have it.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
buffers and access _IO_FILE_complete members of legacy libio streams.
* libio/tst-bz24228.c: New file.
* libio/tst-bz24228.map: Likewise.
* libio/Makefile [build-shared] (tests): Add tst-bz24228.
[build-shared] (generated): Add tst-bz24228.mtrace and
tst-bz24228.check.
[run-built-tests && build-shared] (tests-special): Add
$(objpfx)tst-bz24228-mem.out.
(LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
($(objpfx)tst-bz24228-mem.out): New rule.
This commit is contained in:
@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
|
||||
|
||||
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
|
||||
{
|
||||
int legacy = 0;
|
||||
|
||||
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
|
||||
if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
|
||||
legacy = 1;
|
||||
#endif
|
||||
|
||||
if (! (fp->_flags & _IO_UNBUFFERED)
|
||||
/* Iff stream is un-orientated, it wasn't used. */
|
||||
&& fp->_mode != 0)
|
||||
&& (legacy || fp->_mode != 0))
|
||||
{
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
int cnt;
|
||||
@ -805,7 +812,7 @@ _IO_unbuffer_all (void)
|
||||
__sched_yield ();
|
||||
#endif
|
||||
|
||||
if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
|
||||
if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
|
||||
{
|
||||
fp->_flags |= _IO_USER_BUF;
|
||||
|
||||
@ -816,7 +823,7 @@ _IO_unbuffer_all (void)
|
||||
|
||||
_IO_SETBUF (fp, NULL, 0);
|
||||
|
||||
if (fp->_mode > 0)
|
||||
if (! legacy && fp->_mode > 0)
|
||||
_IO_wsetb (fp, NULL, NULL, 0);
|
||||
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
@ -827,7 +834,8 @@ _IO_unbuffer_all (void)
|
||||
|
||||
/* Make sure that never again the wide char functions can be
|
||||
used. */
|
||||
fp->_mode = -1;
|
||||
if (! legacy)
|
||||
fp->_mode = -1;
|
||||
}
|
||||
|
||||
#ifdef _IO_MTSAFE_IO
|
||||
|
Reference in New Issue
Block a user