Bug 15191

Summary: readelf invalid memory accesses
Product: binutils Reporter: Paul Marinescu <paul.marinescu>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: nickc
Priority: P2    
Version: 2.23   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: valgrind readelf -a bugtest.o

Description Paul Marinescu 2013-02-25 02:48:33 UTC
Created attachment 6892 [details]
valgrind readelf -a bugtest.o

Valgrind shows various invalid memory accesses when running readelf on a particular file (attached). I'm using binutils 2.23.52.20130219
From the output, it seems that readelf detects an invalid sh_entsize, but it nevertheless continues to parse the section.


==29101== Memcheck, a memory error detector
==29101== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==29101== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==29101== Command: /home/pdm110/binutils-pristine/binutils/readelf -a tmpdir/bintest.o.test
==29101== 
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          152 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         0 (2)
  Section header string table index: 7 <corrupt: out of range>
readelf: Error: Section 1 has invalid sh_entsize 200000000000004 (expected 4)

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0] <no-name>         NOTE             0000000000000000  00000000
       0000000000000002  0000000000000000           0     0     0
  [ 1] <no-name>         GROUP            0000000000000000  00000040
       000000000000000c  0000000000000004           8     6     4
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
readelf: Error: Bad sh_link in group section `<no-name>'

There are no program headers in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

No version information found in this file.

Notes at offset 0x00000000 with length 0x00000002:
  Owner                 Data size	Description
==29101== Invalid read of size 1
==29101==    at 0x42EC10: byte_get_little_endian (elfcomm.c:143)
==29101==    by 0x417AF6: process_corefile_note_segment.part.13 (readelf.c:13363)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c9 is 6 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC14: byte_get_little_endian (elfcomm.c:144)
==29101==    by 0x417AF6: process_corefile_note_segment.part.13 (readelf.c:13363)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295ca is 7 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC24: byte_get_little_endian (elfcomm.c:142)
==29101==    by 0x417AF6: process_corefile_note_segment.part.13 (readelf.c:13363)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c8 is 5 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC2A: byte_get_little_endian (elfcomm.c:145)
==29101==    by 0x417AF6: process_corefile_note_segment.part.13 (readelf.c:13363)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295cb is 8 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC2A: byte_get_little_endian (elfcomm.c:145)
==29101==    by 0x417B07: process_corefile_note_segment.part.13 (readelf.c:13364)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c3 is 0 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC10: byte_get_little_endian (elfcomm.c:143)
==29101==    by 0x417B1B: process_corefile_note_segment.part.13 (readelf.c:13366)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c5 is 2 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC14: byte_get_little_endian (elfcomm.c:144)
==29101==    by 0x417B1B: process_corefile_note_segment.part.13 (readelf.c:13366)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c6 is 3 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC24: byte_get_little_endian (elfcomm.c:142)
==29101==    by 0x417B1B: process_corefile_note_segment.part.13 (readelf.c:13366)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c4 is 1 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
==29101== Invalid read of size 1
==29101==    at 0x42EC2A: byte_get_little_endian (elfcomm.c:145)
==29101==    by 0x417B1B: process_corefile_note_segment.part.13 (readelf.c:13366)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101==  Address 0x4c295c7 is 4 bytes after a block of size 3 alloc'd
==29101==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29101==    by 0x402C2C: get_data (readelf.c:325)
==29101==    by 0x417962: process_corefile_note_segment.part.13 (readelf.c:13344)
==29101==    by 0x41EB88: process_object (readelf.c:13341)
==29101==    by 0x420E9B: main (readelf.c:14078)
==29101== 
readelf: Warning: corrupt note found at offset 0 into core notes
readelf: Warning:  type: 0, namesize: 0000457f, descsize: 00000000
==29101== 
==29101== HEAP SUMMARY:
==29101==     in use at exit: 0 bytes in 0 blocks
==29101==   total heap usage: 115 allocs, 115 frees, 14,965 bytes allocated
==29101== 
==29101== All heap blocks were freed -- no leaks are possible
==29101== 
==29101== For counts of detected and suppressed errors, rerun with: -v
==29101== ERROR SUMMARY: 9 errors from 9 contexts (suppressed: 2 from 2)
Comment 1 Sourceware Commits 2013-02-26 17:00:03 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	nickc@sourceware.org	2013-02-26 16:59:52

Modified files:
	binutils       : ChangeLog readelf.c 
	binutils/testsuite: ChangeLog 
	binutils/testsuite/binutils-all: readelf.n 

Log message:
	PR binutils/15191
	* binutils-all/readelf.n: Updare expected output from readelf.
	
	* readelf.c (process_corefile_note_segment): Prevent attempts to
	read beyond the end of the note buffer.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ChangeLog.diff?cvsroot=src&r1=1.1991&r2=1.1992
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/readelf.c.diff?cvsroot=src&r1=1.595&r2=1.596
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/testsuite/ChangeLog.diff?cvsroot=src&r1=1.278&r2=1.279
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/testsuite/binutils-all/readelf.n.diff?cvsroot=src&r1=1.2&r2=1.3
Comment 2 Nick Clifton 2013-02-26 17:02:51 UTC
Hi Paul,

  Thanks for the bug report.  I have checked in a patch to fix the invalid read.  Please update your sources, and if necessary, reopen this bug report.

Cheers
  Nick
Comment 3 Sourceware Commits 2013-02-27 12:40:29 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2013-02-27 12:40:18

Modified files:
	binutils       : ChangeLog readelf.c 

Log message:
	PR binutils/15191
	* readelf.c (offsetof): Define.
	(CHECK_ENTSIZE_VALUES): Remove extraneous indefinite article.
	(process_corefile_note_segment): Allow notes without name or
	desc.  Combine out-of-range checks.  Disallow "negative"
	notesz or descsz.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ChangeLog.diff?cvsroot=src&r1=1.1992&r2=1.1993
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/readelf.c.diff?cvsroot=src&r1=1.596&r2=1.597