From: https://sourceware.org/pipermail/libc-alpha/2024-September/159731.html (This bug was previously reported at <https://bugs.debian.org/1080244>. Although I imagine it is quite a low priority bug, Zack Weinberg suggested I also report it here.) I have an executable that I compiled for i386 in (probably) 1998, which I have been running in a faily cron job. Recently it failed to open a file, and strace showed that the filename was partially corrupted. Since the executable predates the use of ASLR, the memory corruption is reliably reproducible and I was able to catch it with gdb. The memory watchpoint is hit in __GI__IO_link_in() at: 123 _IO_list_all->file._prevchain = &fp->file._chain; 0xf7de4a44 <+612>: lea 0x34(%esi),%ebp 0xf7de4a47 <+615>: mov %ebp,0x64(%ecx) => 0xf7de4a4a <+618>: jmp 0xf7de498a <__GI__IO_link_in+426> 0xf7de4a4f <+623>: nop The backtrace is: #0 0xf7de4a4a in __GI__IO_link_in (fp=0x804a1a0) at ./libio/genops.c:123 #1 0xf7ed9267 in _IO_old_file_init_internal (fp=0x804a1a0) at ./libio/oldfileops.c:106 #2 0xf7ed7e5b in _IO_old_fopen ( filename=0x8049c9c <base_n> "/home/ben/.base-ԡ\004\b", mode=0x8048b43 "r") at ./libio/oldiofopen.c:54 #3 0x0804887a in main () At this point _IO_list_all points to _IO_stderr_, which for some reason is *in the executable's BSS section*: 08049c48 l d .bss 00000000 .bss 08049c9c l O .bss 00000100 base_n.4 08049d9c l O .bss 00000100 rand_n.5 08049e9c l O .bss 00000100 sig_n.6 08049c48 g O .bss 00000050 _IO_stderr_ 08049c98 w .bss 00000004 _environ 08049c98 g O .bss 00000004 __environ 08049c48 g O *ABS* 00000000 __bss_start The size allocated for _IO_stderr_ in the executable appears to be 80 bytes, which is rather smaller than the current size of struct _IO_FILE_plus (152 bytes), so the assignment to _IO_list_all->file._prevchain overwrites the following static data (base_n) containing the filename.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9dfea3de7f690bff70e3c6eb346b9ad082bb2e35 commit 9dfea3de7f690bff70e3c6eb346b9ad082bb2e35 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Sep 7 08:32:32 2024 -0700 libio: Set _vtable_offset before calling _IO_link_in [BZ #32148] Since _IO_vtable_offset is used to detect the old binaries, set it in _IO_old_file_init_internal before calling _IO_link_in which checks _IO_vtable_offset. Add a glibc 2.0 test with copy relocation on _IO_stderr_@GLIBC_2.0 to verify that fopen won't cause memory corruption. This fixes BZ #32148. Signed-off-by: H.J. Lu <hjl.tools@gmail.com> Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
The release/2.40/master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5c06c6e0b5078ffb0aa0c09bac79f086145e0897 commit 5c06c6e0b5078ffb0aa0c09bac79f086145e0897 Author: H.J. Lu <hjl.tools@gmail.com> Date: Sat Sep 7 08:32:32 2024 -0700 libio: Set _vtable_offset before calling _IO_link_in [BZ #32148] Since _IO_vtable_offset is used to detect the old binaries, set it in _IO_old_file_init_internal before calling _IO_link_in which checks _IO_vtable_offset. Add a glibc 2.0 test with copy relocation on _IO_stderr_@GLIBC_2.0 to verify that fopen won't cause memory corruption. This fixes BZ #32148. Signed-off-by: H.J. Lu <hjl.tools@gmail.com> Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com> (cherry picked from commit 9dfea3de7f690bff70e3c6eb346b9ad082bb2e35)
Fixed for glibc 2.41 and 2.40 branch.
(In reply to H.J. Lu from comment #3) > Fixed for glibc 2.41 and 2.40 branch. Marking fixed then.