Bug 90077 - fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
Summary: fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 9
Hardware: i686
OS: Linux
high
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2003-05-02 02:49 UTC by Ezra Peisach
Modified: 2016-11-24 15:25 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-05-07 03:47:54 UTC
Embargoed:


Attachments (Terms of Use)
libio patch to test libc errata (1.08 KB, patch)
2003-11-06 06:21 UTC, Ezra Peisach
no flags Details | Diff
Program to demonstrate failure of glibc compat fopen in libc errata (20.00 KB, application/octet-stream)
2003-11-06 19:48 UTC, Ezra Peisach
no flags Details
Corrected program to demonstrate failure of glibc compat fopen (10.00 KB, application/octet-stream)
2003-11-06 20:04 UTC, Ezra Peisach
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2003:325 0 normal SHIPPED_LIVE : Updated glibc packages provide security and bug fixes 2003-11-12 05:00:00 UTC

Description Ezra Peisach 2003-05-02 02:49:15 UTC
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:

Comment 1 Ulrich Drepper 2003-05-07 03:47:54 UTC
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.

Comment 2 Ulrich Drepper 2003-11-04 21:43:09 UTC
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.

Comment 3 Ezra Peisach 2003-11-05 19:08:44 UTC
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



Comment 4 Ezra Peisach 2003-11-05 20:37:18 UTC
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.

Comment 5 Ezra Peisach 2003-11-06 06:21:29 UTC
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 *

Comment 6 Ezra Peisach 2003-11-06 19:48:32 UTC
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

Comment 7 Ezra Peisach 2003-11-06 20:04:56 UTC
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

Comment 8 Jakub Jelinek 2003-11-07 17:53:47 UTC
Your testcase is very broken.  You shouldn't ever use ld -shared
directly to build a shared library.

Comment 9 Ezra Peisach 2003-11-07 18:56:00 UTC
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




Note You need to log in before you can comment on or make changes to this bug.