Red Hat Bugzilla – Bug 90077
fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
Last modified: 2016-11-24 10:25:31 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225
Description of problem:
An application that winds up using thr GLIBC_2_0 fopen oldio code in
the C library will allocate memory that gets immediatly corrupted. This
can result in subsequent coredumps in malloc.
In the glibc source tree, the probem stems from libio/libio.h header file in the
definition of _IO_FILE. If _IO_USE_OLD_IO_FILE is defined, the structure is
shorter than w/o this defintion.
Now, libio/oldiofopen.c defined _IO_USE_OLD_IO_FILE, and malloc's memory based
on this shortened structure. This would be okay, but _IO_init is invoken.
_IO_init is in libio/genops.c - and does not define _IO_USE_OLD_IO_FILE.
_IO_init invokes _IO_no_init which
assigns fp->_mode (line 636). _mode is not present in the truncated
_IO_FILE that is allocated.
From my initial looking at the code, it appears that there are
multiple code paths in which the old IO_FILE structure is referenced
in which _mode is referenced.
I originally thought of making an _IO_no_init_internal with an old
version flag - but then I believe the _mode field is tested in several places.
Possibly there is another test that would indicate whether the
extended structure is in use or the truncated one - before testing the
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1.I can reproduce by using dmalloc and ccp4-4.4.2
2. Check at interval 1 - in the first malloc after fopen, the upper fencepost is
Actual Results: dmalloc coredumps. The program coredumps if not running dmalloc.
Expected Results: Programs should not die on startup.
I've checked in some changes into the official glibc archive which make sure
_mode is not touched. No other place then _IO_init should have caused this so
this is safe.
The upcoming RHL9 errata has a number of changes in this area. Get a
test release from
and let us know whether it works.
I have tested the rpms. The initial failure that I was observing is
not there. System boots, and I am able to function - so I would say it
looks like a success. I will continue to test and see if anything else
Additional testing using dmalloc in a newer version of the code being
tested is still showing a memory corruption. The code path right now
is fopen, fstat(fileno), calloc - where dmalloc detects failure.
I have verified that fopen is at fault - and will track it down tonight.
Created attachment 95756 [details]
libio patch to test libc errata
I have tracked down the problem.
In glibc-libio-compat.patch - on Aug 25, Ulrich added a change to
libio/oldfileops.c to initialize _mode.
This change is in _IO_old_file_init. The basic assumption is that if
_IO_stdin_used is set, then the memory allocated to fp is for a
_IO_FILE_complete and not just a _IO_FILE_plus. (in my reading, csu/init.c
always sets _IO_stdin_used.
Now here's the problem:
All invocatoins of _IO_old_file_init in libio/*.c really only allocate the
smaller _IO_FILE_plus size. (see oldiofopen.c for instance)
But, if one uses the _IO_file_init compat symbol - which I suppose could be
invoked from a GLIBC 2.1 version - which allocates the larger sized structure.
What is needed is a method to ascertain if the old file handlers are involved
I have come up with the following simple patch. I believe the JUMPS table will
always be initialized to the old table when the old
io is used for the FILE *
Created attachment 95770 [details]
Program to demonstrate failure of glibc compat fopen in libc errata
This tar archive contains a Makefile, and two source files that demonstrates
the glibc failure mode. It uses dmalloc to demonstrate the test.
Essentially, when the first (only probably) libio fopen comes from a shared
library, the GLIBC 2.0 version is invoked - otherwise the new interface is
This test creates a shared library, links it into program using dmalloc. The
test case in the Makefile sets up dmalloc to check every memory allocation for
a corrupt arena. (-i 1), debug level high.
fopen is invoked in the library, and then a simple memory allocation is carried
dmalloc detects the fencepost overwrite in fopen and aborts.
If I apply my patch (95756) to libc, the program works.
Created attachment 95772 [details]
Corrected program to demonstrate failure of glibc compat fopen
Made a error in packaging last time.... Same report, proper files this time.
Your testcase is very broken. You shouldn't ever use ld -shared
directly to build a shared library.
Hmm.. while I agree building a shared library in this manner may be
broken. This is how a third party package did the deed.
It does demonstrate the glibc failure... I will look into convincing
the other people to build their shared library in a better fashion...
(but I can tell you right now, the libraries work under RH8 -
transfering the executable to rh9 breaks)