Bug 90077 - fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
Status: CLOSED UPSTREAM
Product: Red Hat Linux
Classification: Retired
Component: glibc (Show other bugs)
9
i686 Linux
high Severity high
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2003-05-01 22:49 EDT by Ezra Peisach
Modified: 2016-11-24 10:25 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2003-05-06 23:47:54 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
libio patch to test libc errata (1.08 KB, patch)
2003-11-06 01:21 EST, 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 14:48 EST, Ezra Peisach
no flags Details
Corrected program to demonstrate failure of glibc compat fopen (10.00 KB, application/octet-stream)
2003-11-06 15:04 EST, Ezra Peisach
no flags Details

  None (edit)
Description Ezra Peisach 2003-05-01 22:49:15 EDT
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-06 23:47:54 EDT
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 16:43:09 EST
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 14:08:44 EST
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 15:37:18 EST
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 01:21:29 EST
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 14:48:32 EST
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 15:04:56 EST
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 12:53:47 EST
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 13:56:00 EST
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.