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 extended fields. Version-Release number of selected component (if applicable): glibc-2.3.2-27.9 How reproducible: Always 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 overwritten. 3. Actual Results: dmalloc coredumps. The program coredumps if not running dmalloc. Expected Results: Programs should not die on startup. Additional info:
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 ftp://people.redhat.com/jakub/glibc/errata/2.3.2-27.9.4/ 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 is broken. Ezra
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 or not. 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 used. 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 out. dmalloc detects the fencepost overwrite in fopen and aborts. If I apply my patch (95756) to libc, the program works. Ezra
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. Ezra
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) Ezra