Bug 90077
| Summary: | fopen@GLIBC_2_0 corrupts memory arena by buffer overrun | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Retired] Red Hat Linux | Reporter: | Ezra Peisach <epeisach> | ||||||||
| Component: | glibc | Assignee: | Jakub Jelinek <jakub> | ||||||||
| Status: | CLOSED UPSTREAM | QA Contact: | Brian Brock <bbrock> | ||||||||
| Severity: | high | Docs Contact: | |||||||||
| Priority: | high | ||||||||||
| Version: | 9 | CC: | fweimer | ||||||||
| Target Milestone: | --- | ||||||||||
| Target Release: | --- | ||||||||||
| Hardware: | i686 | ||||||||||
| OS: | Linux | ||||||||||
| Whiteboard: | |||||||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||||||
| Doc Text: | Story Points: | --- | |||||||||
| Clone Of: | Environment: | ||||||||||
| Last Closed: | 2003-05-07 03:47:54 UTC | Type: | --- | ||||||||
| Regression: | --- | Mount Type: | --- | ||||||||
| Documentation: | --- | CRM: | |||||||||
| Verified Versions: | Category: | --- | |||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||
| Embargoed: | |||||||||||
| Attachments: |
|
||||||||||
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 |
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: