Bug 178159

Summary: use after free() when DT_NEEDED shared library not found
Product: [Fedora] Fedora Reporter: John Reiser <jreiser>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED UPSTREAM QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 5   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-01-20 15:24:12 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:

Description John Reiser 2006-01-18 03:44:47 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8) Gecko/20060103 Fedora/1.5-4 Firefox/1.5

Description of problem:
If a DT_NEEDED shared library cannot be opened, then _dl_map_object_deps calls _dl_signal_error with a dangling objname parameter that points into the same block as the old errstring, which was free()d at dl-deps.c:251.  _dl_signal_error then accesses the freed block to compute strlen(objname) and memcpy it, too.

Internal testcase elf/neededtest4 illustrates the problem.  The DT_NEEDED shared object that is not found is neededobj5.so on the second request for it, after it has been renamed temporarily to neededobj5.so.renamed.  The errstring and objname were copied into the same newly-mallo()ed block on the previous call to _dl_signal_error.

It looks like everywhere _dl_map_object_deps calls strdupa(errstring) it should also call strdupa(objname).


Version-Release number of selected component (if applicable):
glibc-2.3.90-29

How reproducible:
Always

Steps to Reproduce:
1. Run internal testcase elf/neededtest4 under gdb.  (This may require altering the entry of [a copy of] ld.so to be 'int3' so that gdb can gain control, and compensating for the clobbered "mov %esp,%eax".)
2. Put a breakpoint on the "free((char *)errstring);" at dl-deps.c:251 and execute until there.  Note the values of errstring and objname.
3. Put a breakpoint on _dl_signal_error, and note the value of objname.
  

Actual Results:  The errstring and objname are adjacent in the same malloc()ed block, with errstring at the head, when _dl_map_object_deps calls free(errstring) at dl-deps.c:251.  The objname still dangles into the freed block when _dl_signal_error is reached.

Expected Results:  No access to a malloc()ed block after it has been free()d.  objname should be copied whenever errstring is (or some other suitable fix.)

Additional info:

Spotted by memory access checking tools, including valgrind-3.1.0.

Comment 1 John Reiser 2006-01-18 04:06:04 UTC
The same error also affects testcases elf/tst-dlmopen1 and elf/tst-dlmopen3.

Comment 3 Jakub Jelinek 2006-01-20 15:24:12 UTC
Fixed in CVS.