This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
readelf build error on 64-bit hosts
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org, Nick Clifton <nickc at redhat dot com>
- Date: Wed, 27 Feb 2013 21:03:18 +1030
- Subject: readelf build error on 64-bit hosts
Hi Nick,
>From the PR15181 fix, I believe..
readelf.c: In function âprocess_corefile_note_segmentâ:
readelf.c:13370:23: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
readelf.c:13391:23: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
On looking at the change, I think there are some other errors too. This:
Elf_External_Note * next;
..
if (data_remaining < sizeof * next)
will cause a failure if the last note in a note section has namesz and
descsz both zero (Elf_External_Note includes a one byte name array).
What do you think of the following?
* 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 descaz.
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.596
diff -u -p -r1.596 readelf.c
--- binutils/readelf.c 26 Feb 2013 16:59:51 -0000 1.596
+++ binutils/readelf.c 27 Feb 2013 10:06:36 -0000
@@ -160,6 +160,10 @@
#include "safe-ctype.h"
#include "filenames.h"
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
+#endif
+
char * program_name = "readelf";
static long archive_file_offset;
static unsigned long archive_file_size;
@@ -4754,7 +4758,7 @@ process_section_headers (FILE * file)
bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
if (section->sh_entsize != expected_entsize) \
{ \
- error (_("Section %d has invalid an sh_entsize of %" BFD_VMA_FMT "x\n"), \
+ error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
i, section->sh_entsize); \
error (_("(Using the expected size of %d for the rest of this dump)\n"), \
(int) expected_entsize); \
@@ -13340,7 +13344,6 @@ process_corefile_note_segment (FILE * fi
Elf_External_Note * pnotes;
Elf_External_Note * external;
int res = 1;
- bfd_signed_vma data_remaining;
if (length <= 0)
return 0;
@@ -13356,18 +13359,20 @@ process_corefile_note_segment (FILE * fi
(unsigned long) offset, (unsigned long) length);
printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
- data_remaining = length;
- while (external < (Elf_External_Note *) ((char *) pnotes + length))
+ while ((char *) external < (char *) pnotes + length)
{
- Elf_External_Note * next;
Elf_Internal_Note inote;
+ size_t min_notesz;
+ char *next;
char * temp = NULL;
+ size_t data_remaining = ((char *) pnotes + length) - (char *) external;
if (!is_ia64_vms ())
{
/* PR binutils/15191
Make sure that there is enough data to read. */
- if (data_remaining < sizeof * next)
+ min_notesz = offsetof (Elf_External_Note, name);
+ if (data_remaining < min_notesz)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
@@ -13379,8 +13384,7 @@ process_corefile_note_segment (FILE * fi
inote.descsz = BYTE_GET (external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
-
- next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
+ next = inote.descdata + align_power (inote.descsz, 2);
}
else
{
@@ -13388,7 +13392,8 @@ process_corefile_note_segment (FILE * fi
/* PR binutils/15191
Make sure that there is enough data to read. */
- if (data_remaining < sizeof * vms_external)
+ min_notesz = offsetof (Elf64_External_VMS_Note, name);
+ if (data_remaining < min_notesz)
{
warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
(int) data_remaining);
@@ -13402,33 +13407,21 @@ process_corefile_note_segment (FILE * fi
inote.descsz = BYTE_GET (vms_external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 3);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
-
- next = (Elf_External_Note *)
- (inote.descdata + align_power (inote.descsz, 3));
+ next = inote.descdata + align_power (inote.descsz, 3);
}
- data_remaining -= ((char *) next - (char *) external);
- if (data_remaining < 0)
+ if (inote.descdata < (char *) external + min_notesz
+ || next < (char *) external + min_notesz
+ || data_remaining < (size_t)(next - (char *) external))
{
- warn (_("note with invalid namesz &/or descsz found at offset 0x%lx\n"),
+ warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
(unsigned long) ((char *) external - (char *) pnotes));
warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
inote.type, inote.namesz, inote.descsz);
break;
}
- external = next;
-
- /* Prevent out-of-bounds indexing. */
- if (inote.namedata + inote.namesz > (char *) pnotes + length
- || inote.namedata + inote.namesz < inote.namedata)
- {
- warn (_("note with invalid namesz found at offset 0x%lx\n"),
- (unsigned long) ((char *) external - (char *) pnotes));
- warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
- inote.type, inote.namesz, inote.descsz);
- break;
- }
+ external = (Elf_External_Note *) next;
/* Verify that name is null terminated. It appears that at least
one version of Linux (RedHat 6.0) generates corefiles that don't
--
Alan Modra
Australia Development Lab, IBM