From 470c009be81f3ac0205d4efb1d16fc4216093b69 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 14 Nov 2014 13:39:29 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 7 +++++++ bfd/opncls.c | 15 ++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4f28398b734..015acda560a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2014-11-14 Nick Clifton + + 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 PR binutils/17512 diff --git a/bfd/opncls.c b/bfd/opncls.c index a22fba0b096..75af627d293 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); -- 2.30.2