According to report in https://bugzilla.altlinux.org/36065, old x86 applications that use legacy libio crash on exit under valgrind: $ valgrind ./cat /dev/null ==26578== Memcheck, a memory error detector ==26578== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==26578== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==26578== Command: ./cat /dev/null ==26578== ==26578== Invalid read of size 4 ==26578== at 0x40B0AFA: _IO_wsetb (wgenops.c:96) ==26578== by 0x40BB681: _IO_unbuffer_all (genops.c:883) ==26578== by 0x40BB681: _IO_cleanup (genops.c:930) ==26578== by 0x4076E01: __run_exit_handlers (exit.c:130) ==26578== by 0x4076E40: exit (exit.c:139) ==26578== by 0x804991F: ??? (in /usr/src/cat) ==26578== by 0x8048EB9: ??? (in /usr/src/cat) ==26578== Address 0x18 is not stack'd, malloc'd or (recently) free'd ==26578== ==26578== ==26578== Process terminating with default action of signal 11 (SIGSEGV) ==26578== Access not within mapped region at address 0x18 ==26578== at 0x40B0AFA: _IO_wsetb (wgenops.c:96) ==26578== by 0x40BB681: _IO_unbuffer_all (genops.c:883) ==26578== by 0x40BB681: _IO_cleanup (genops.c:930) ==26578== by 0x4076E01: __run_exit_handlers (exit.c:130) ==26578== by 0x4076E40: exit (exit.c:139) ==26578== by 0x804991F: ??? (in /usr/src/cat) ==26578== by 0x8048EB9: ??? (in /usr/src/cat) I think this happens due to commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305) that introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to free wide buffers of all files, including legacy standard files that are small statically allocated objects that do not have wide buffers. The proposed fix is to skip _IO_wsetb() invocation for legacy standard files.
Proposed patch: https://sourceware.org/ml/libc-alpha/2019-02/msg00442.html
I have a somewhat hacked-together reproducer. The behavior depends on what is next to _IO_stdout_ etc. in the process image (possibly after interposition). In most cases, fp->_mode does not appear to be positive, so we do not call _IO_wsetb by accident.
Patch with a different test case: https://sourceware.org/ml/libc-alpha/2019-02/msg00476.html
Note that this also affects OpenJDK 8 binaries for i386, even if they are linked against current glibc because OpenJDK uses a linker script which suppresses output of the _IO_stdin_used variable.
The master branch has been updated by Dmitry Levin <ldv@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=21cc130b78a4db9113fb6695e2b951e697662440 commit 21cc130b78a4db9113fb6695e2b951e697662440 Author: Dmitry V. Levin <ldv@altlinux.org> Date: Wed Feb 13 01:20:51 2019 +0000 libio: do not attempt to free wide buffers of legacy streams [BZ #24228] Commit a601b74d31ca086de38441d316a3dee24c866305 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.
Fixed in glibc 2.30.
The release/2.27/master branch has been updated by Dmitry Levin <ldv@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f056ac8363442b0b14d2a7eccc2cd14c5f3b6ce2 commit f056ac8363442b0b14d2a7eccc2cd14c5f3b6ce2 Author: Dmitry V. Levin <ldv@altlinux.org> Date: Wed Feb 13 01:20:51 2019 +0000 libio: do not attempt to free wide buffers of legacy streams [BZ #24228] Commit a601b74d31ca086de38441d316a3dee24c866305 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. (cherry picked from commit 21cc130b78a4db9113fb6695e2b951e697662440)
The release/2.28/master branch has been updated by Dmitry Levin <ldv@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=91b02c5b4d17d60015af24d277eb31348fc0bc34 commit 91b02c5b4d17d60015af24d277eb31348fc0bc34 Author: Dmitry V. Levin <ldv@altlinux.org> Date: Wed Feb 13 01:20:51 2019 +0000 libio: do not attempt to free wide buffers of legacy streams [BZ #24228] Commit a601b74d31ca086de38441d316a3dee24c866305 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. (cherry picked from commit 21cc130b78a4db9113fb6695e2b951e697662440)
The release/2.29/master branch has been updated by Dmitry Levin <ldv@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=34fb5f61d3c3f4b8fc616ea259fa19168b58ecd4 commit 34fb5f61d3c3f4b8fc616ea259fa19168b58ecd4 Author: Dmitry V. Levin <ldv@altlinux.org> Date: Wed Feb 13 01:20:51 2019 +0000 libio: do not attempt to free wide buffers of legacy streams [BZ #24228] Commit a601b74d31ca086de38441d316a3dee24c866305 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. (cherry picked from commit 21cc130b78a4db9113fb6695e2b951e697662440)
This particular fix comes with a test that seems to be executed on all architectures even though it seems to be x86-specific. Is this intentional? It fails on sparc64: ---------- FAIL: libio/tst-bz24228 original exit status 138 ---------- Full log: https://buildd.debian.org/status/fetch.php?pkg=glibc&arch=sparc64&ver=2.29-1&stamp=1568193377&raw=0
(In reply to John Paul Adrian Glaubitz from comment #10) > This particular fix comes with a test that seems to be executed on all > architectures even though it seems to be x86-specific. > > Is this intentional? Yes, it affects some MIPS architectures as well. > It fails on sparc64: > > ---------- > FAIL: libio/tst-bz24228 > original exit status 138 > ---------- > > Full log: > https://buildd.debian.org/status/fetch.php?pkg=glibc&arch=sparc64&ver=2.29- > 1&stamp=1568193377&raw=0 Please open a separate bug for that and provide a build log with -O, so that make attributes error message to the right commands. Thanks. (Enabling -O by default should be safe for Debian glibc builds, given that make is current, and it is advertised as not affecting performance, but the build log will be slightly larger.)
(In reply to Florian Weimer from comment #11) > Please open a separate bug for that and provide a build log with -O, so that > make attributes error message to the right commands. Thanks. (Enabling -O > by default should be safe for Debian glibc builds, given that make is > current, and it is advertised as not affecting performance, but the build > log will be slightly larger.) Okay, working on it.