Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 90077

Summary: fopen@GLIBC_2_0 corrupts memory arena by buffer overrun
Product: [Retired] Red Hat Linux Reporter: Ezra Peisach <epeisach>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED UPSTREAM QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: high    
Version: 9CC: 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:
Description Flags
libio patch to test libc errata
none
Program to demonstrate failure of glibc compat fopen in libc errata
none
Corrected program to demonstrate failure of glibc compat fopen none

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