bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Memory read out of bound in readelf from binutils-2.24


From: xiaoqixue_1
Subject: Memory read out of bound in readelf from binutils-2.24
Date: Wed, 28 Jan 2015 14:30:51 +0800 (CST)

Advisory: Memory read out of bound in readelf from binutils-2.24.
Advisory ID: -
Author : Qixue Xiao
Affected Sofware:  binutils-2.22 - 2.24,(tested), may be more versions
Vendor URL: http://www.gnu.org/software/binutils/
Vendor Status:  
CVE-ID : -

 
================================

 Description:

================================

 
There is a memory read out of bound in readelf from binutils-2.24.

 
=========================================

Details:

 
=========================================
 

When readelf with a incorrect binary , it will read 4 bytes out of a allocated 
heap, a part of the results output by valgrind as follows:

valgrind readelf -a -w a.out


==32007== Invalid read of size 1
==32007==    at 0x446685: byte_get_little_endian (elfcomm.c:151)
==32007==    by 0x42CA3B: print_gnu_note (readelf.c:13268)
==32007==    by 0x42D62D: process_note (readelf.c:13578)
==32007==    by 0x42DB12: process_corefile_note_segment (readelf.c:13695)
==32007==    by 0x42DC41: process_note_sections (readelf.c:13743)
==32007==    by 0x42DC9E: process_notes (readelf.c:13758)
==32007==    by 0x42E4A5: process_object (readelf.c:13973)
==32007==    by 0x42F331: process_file (readelf.c:14342)
==32007==    by 0x42F48C: main (readelf.c:14407)
==32007==  Address 0x541775f is 2 bytes after a block of size 29 alloc'd
==32007==    at 0x4C2B6CD: malloc (in 
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32007==    by 0x40889D: get_data (readelf.c:328)
==32007==    by 0x42D72F: process_corefile_note_segment (readelf.c:13598)
==32007==    by 0x42DC41: process_note_sections (readelf.c:13743)
==32007==    by 0x42DC9E: process_notes (readelf.c:13758)
==32007==    by 0x42E4A5: process_object (readelf.c:13973)
==32007==    by 0x42F331: process_file (readelf.c:14342)
==32007==    by 0x42F48C: main (readelf.c:14407)
==32007==

=================================================
some important code
=================================================

13588 static int
13589 process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma 
length)
13590 {
...

13597
13598   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13599                        _("notes"));
13600   if (pnotes == NULL)
13601     return 0;
13602
13603   external = pnotes;
13604
13605   printf (_("\nDisplaying notes found at file offset 0x%08lx with length 
0x%08lx:\n"),
13606       (unsigned long) offset, (unsigned long) length);
13607   printf (_("  %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
13608
13609   while ((char *) external < (char *) pnotes + length)
13610     {
13611       Elf_Internal_Note inote;
13612       size_t min_notesz;
13613       char *next;
13614       char * temp = NULL;
13615       size_t data_remaining = ((char *) pnotes + length) - (char *) 
external;
13616
13617       if (!is_ia64_vms ())
13618     {
13619       /* PR binutils/15191
13620          Make sure that there is enough data to read.  */
13621       min_notesz = offsetof (Elf_External_Note, name);
13622       if (data_remaining < min_notesz)
13623         {
13624           warn (_("Corrupt note: only %d bytes remain, not enough for a 
full note\n"),
13625             (int) data_remaining);
13626           break;
13627         }
13628       inote.type     = BYTE_GET (external->type);
13629       inote.namesz   = BYTE_GET (external->namesz);
13630       inote.namedata = external->name;
13631       inote.descsz   = BYTE_GET (external->descsz);
13632       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13633       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
13634       next = inote.descdata + align_power (inote.descsz, 2);
13635     }
13636       else
13637     {

....

13694
13695       res &= process_note (& inote);

 

 ........

13265     os = byte_get ((unsigned char *) pnote->descdata, 4);
13266     major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13267     minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13268     subminor = byte_get ((unsigned char *) pnote->descd

Attachment: testcase.zip
Description: Zip compressed data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]