aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-11-14 13:39:29 +0000
committerNick Clifton <nickc@redhat.com>2014-11-14 13:39:29 +0000
commit470c009be81f3ac0205d4efb1d16fc4216093b69 (patch)
treebb5f813a1f7addcc8bfa4014b9c87cbaa508cc95
parent02c1355124de323e32b8b47fa0b19c114549756a (diff)
downloadgdb-470c009be81f3ac0205d4efb1d16fc4216093b69.zip
gdb-470c009be81f3ac0205d4efb1d16fc4216093b69.tar.gz
gdb-470c009be81f3ac0205d4efb1d16fc4216093b69.tar.bz2
Fix a null pointer dereference when reading the debug link info from a corrupt file.
PR binutils/17597 * opncls.c (bfd_get_debug_link_info): Avoid reading off the end of the section. (bfd_get_alt_debug_link_info): Likewise.
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/opncls.c15
2 files changed, 17 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4f28398..015acda 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
2014-11-14 Nick Clifton <nickc@redhat.com>
+ PR binutils/17597
+ * opncls.c (bfd_get_debug_link_info): Avoid reading off the end of
+ the section.
+ (bfd_get_alt_debug_link_info): Likewise.
+
+2014-11-14 Nick Clifton <nickc@redhat.com>
+
PR binutils/17512
* ieee.c (ieee_archive_p) Skip processing if no bytes are read at
all.
diff --git a/bfd/opncls.c b/bfd/opncls.c
index a22fba0..75af627 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -1170,7 +1170,7 @@ bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
asection *sect;
unsigned long crc32;
bfd_byte *contents;
- int crc_offset;
+ unsigned int crc_offset;
char *name;
BFD_ASSERT (abfd);
@@ -1188,10 +1188,13 @@ bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
return NULL;
}
- /* Crc value is stored after the filename, aligned up to 4 bytes. */
+ /* CRC value is stored after the filename, aligned up to 4 bytes. */
name = (char *) contents;
- crc_offset = strlen (name) + 1;
+ /* PR 17597: avoid reading off the end of the buffer. */
+ crc_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
crc_offset = (crc_offset + 3) & ~3;
+ if (crc_offset >= bfd_get_section_size (sect))
+ return NULL;
crc32 = bfd_get_32 (abfd, contents + crc_offset);
@@ -1223,7 +1226,7 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
{
asection *sect;
bfd_byte *contents;
- int buildid_offset;
+ unsigned int buildid_offset;
char *name;
BFD_ASSERT (abfd);
@@ -1244,7 +1247,9 @@ bfd_get_alt_debug_link_info (bfd * abfd, bfd_size_type *buildid_len,
/* BuildID value is stored after the filename. */
name = (char *) contents;
- buildid_offset = strlen (name) + 1;
+ buildid_offset = strnlen (name, bfd_get_section_size (sect)) + 1;
+ if (buildid_offset >= bfd_get_section_size (sect))
+ return NULL;
*buildid_len = bfd_get_section_size (sect) - buildid_offset;
*buildid_out = bfd_malloc (*buildid_len);