Bug 730336

Summary: The libmagic ELF Program Header table parser does not work correctly
Product: Red Hat Enterprise Linux 6 Reporter: David Howells <dhowells>
Component: fileAssignee: Jan Kaluža <jkaluza>
Status: CLOSED ERRATA QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: urgent Docs Contact:
Priority: urgent    
Version: 6.1CC: borgan, ddumas, jwest, kbaker, mvadkert, ovasik, santiago, syeghiay
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: file-5.04-10.el6 Doc Type: Bug Fix
Doc Text:
Prior to this update, the file utility did not parse ELF (Executable and Linkable Format) binary files correctly. If an entry in the program header table contained a file offset beyond the end of file (EOF) character, dynamically linked files were reported as being linked statically. This bug has been fixed, and the file utility now recognizes files in the described scenario correctly.
Story Points: ---
Clone Of:
: 730676 (view as bug list) Environment:
Last Closed: 2011-09-07 13:38:55 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:
Bug Depends On:    
Bug Blocks: 730347, 730676, 731336    
Attachments:
Description Flags
Test data: pre-RELRO debug file from keyutils
none
Test data: post-RELRO debug file from keyutils
none
proposed patch none

Description David Howells 2011-08-12 14:24:42 UTC
Description of problem:

The libmagic ELF Program Header parser (dophn_exec()) does not work correctly.  If an entry in the table has a file offset beyond the EOF then the loop working through the table does not ever advance beyond that entry because the following clause:

		if (xph_offset > st.st_size && savedoffset != (off_t)-1) {
			if (lseek(fd, savedoffset, SEEK_SET) == (off_t)-1) {
				file_badseek(ms);
				return -1;
			}
			continue;
		}

Rewinds the file pointer again and again.  I would recommend prefacing the read with a seek directly into the table based on the offset of the table in the file plus the multiplication of the entry size by the entry number rather than trying to save the file pointer and then going back to it.

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

file-5.04-6.el6.ppc64
file-5.04-17.fc14.x86_64

How reproducible:

100%.

Steps to Reproduce:
1. Grab the two attached debuginfo files.
2. Run file on them.
  
Actual results:

warthog>file /tmp/old-keyctl.debug 
/tmp/old-keyctl.debug: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
warthog>file /tmp/new-keyctl.debug 
/tmp/new-keyctl.debug: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), statically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

The new-keyctl.debug file should say 'dynamically' linked.

Expected results:

Both should say the same - both should be 'dynamically' linked.

Additional info:

This can be triggered by building the keyutils package for ppc and ppc64.  The "-Wl,-z,relro" flag causes a change in the configuration of the program header tables.  Note the file offset in the second PT_LOAD segment.  The new binary is 0xd528 in size.

warthog>objdump -p /tmp/old-keyctl.debug 

/tmp/old-keyctl.debug:     file format elf64-big

Program Header:
    PHDR off    0x0000000000000040 vaddr 0x0000000010000040 paddr 0x0000000010000040 align 2**3
         filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags r-x
  INTERP off    0x0000000000000200 vaddr 0x0000000010000200 paddr 0x0000000010000200 align 2**0
         filesz 0x0000000000000011 memsz 0x0000000000000011 flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000010000000 paddr 0x0000000010000000 align 2**16
         filesz 0x0000000000005794 memsz 0x0000000000005794 flags r-x
    LOAD off    0x0000000000005798 vaddr 0x0000000010015798 paddr 0x0000000010015798 align 2**16
         filesz 0x00000000000007c8 memsz 0x0000000000010cb8 flags rw-
 DYNAMIC off    0x00000000000057c0 vaddr 0x00000000100157c0 paddr 0x00000000100157c0 align 2**3
         filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags rw-
    NOTE off    0x0000000000000214 vaddr 0x0000000010000214 paddr 0x0000000010000214 align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x0000000000004ef8 vaddr 0x0000000010004ef8 paddr 0x0000000010004ef8 align 2**2
         filesz 0x0000000000000154 memsz 0x0000000000000154 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

Dynamic Section:

warthog>objdump -p /tmp/new-keyctl.debug 

/tmp/new-keyctl.debug:     file format elf64-big

Program Header:
    PHDR off    0x0000000000000040 vaddr 0x0000000010000040 paddr 0x0000000010000040 align 2**3
         filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r-x
  INTERP off    0x0000000000000238 vaddr 0x0000000010000238 paddr 0x0000000010000238 align 2**0
         filesz 0x0000000000000011 memsz 0x0000000000000011 flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000010000000 paddr 0x0000000010000000 align 2**16
         filesz 0x0000000000005724 memsz 0x0000000000005724 flags r-x
    LOAD off    0x000000000000fe18 vaddr 0x000000001001fe18 paddr 0x000000001001fe18 align 2**16
         filesz 0x00000000000007c8 memsz 0x0000000000010cb8 flags rw-
 DYNAMIC off    0x000000000000fe40 vaddr 0x000000001001fe40 paddr 0x000000001001fe40 align 2**3
         filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags rw-
    NOTE off    0x000000000000024c vaddr 0x000000001000024c paddr 0x000000001000024c align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x0000000000004ec8 vaddr 0x0000000010004ec8 paddr 0x0000000010004ec8 align 2**2
         filesz 0x0000000000000154 memsz 0x0000000000000154 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
   RELRO off    0x000000000000fe18 vaddr 0x000000001001fe18 paddr 0x000000001001fe18 align 2**0
         filesz 0x00000000000001e8 memsz 0x00000000000001e8 flags r--

Dynamic Section:

Comment 2 David Howells 2011-08-12 14:28:17 UTC
Created attachment 518037 [details]
Test data: pre-RELRO debug file from keyutils

Comment 3 David Howells 2011-08-12 14:29:20 UTC
Created attachment 518039 [details]
Test data: post-RELRO debug file from keyutils

Comment 5 RHEL Program Management 2011-08-12 14:48:04 UTC
This request was evaluated by Red Hat Product Management for
inclusion in the current release of Red Hat Enterprise Linux.
Because the affected component is not scheduled to be updated
in the current release, Red Hat is unfortunately unable to
address this request at this time. Red Hat invites you to
ask your support representative to propose this request, if
appropriate and relevant, in the next release of Red Hat
Enterprise Linux. If you would like it considered as an
exception in the current release, please ask your support
representative.

Comment 6 Jan Kaluža 2011-08-15 10:53:44 UTC
Created attachment 518249 [details]
proposed patch

Comment 7 Jan Kaluža 2011-08-15 10:54:07 UTC
Proposed patch fixes the problem for me. I will send it upstream.

Comment 8 David Howells 2011-08-15 11:35:57 UTC
It works for me when applied to the RHEL-6 package.

One note: the parser now goes backwards through the program header table instead of forwards.  I don't think this should make a difference, though.

Comment 9 Jan Kaluža 2011-08-15 11:54:33 UTC
Yeah, it goes backward but it should not cause any problem. It should not matter.

Comment 11 Jan Kaluža 2011-08-16 08:03:00 UTC
This issue is reported upstream as http://bugs.gw.com/view.php?id=134

Comment 18 Tomas Capek 2011-08-17 15:56:23 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
Prior to this update, the file utility did not parse ELF (Executable and Linkable Format) binary files correctly. If an entry in the program header table contained a file offset beyond the end of file (EOF) character, dynamically linked files were reported as being linked statically. This bug has been fixed, and the file utility now recognizes files in the described scenario correctly.

Comment 19 David Howells 2011-08-23 08:05:44 UTC
(In reply to comment #18)
> Prior to this update, the file utility did not parse ELF (Executable and
> Linkable Format) binary files correctly. If an entry in the program header
> table contained a file offset beyond the end of file (EOF) character,
> dynamically linked files were reported as being linked statically. This bug has
> been fixed, and the file utility now recognizes files in the described scenario
> correctly.

There isn't really an EOF character, per se.  I would drop the word 'character' from that.

Comment 26 errata-xmlrpc 2011-09-07 13:38:55 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-0934.html