summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2019-01-20 22:10:18 +0100
committerMark Wielaard <mark@klomp.org>2019-01-22 18:12:38 +0100
commit2562759d6fe5b364fe224852e64e8bda39eb2e35 (patch)
tree40b5cf97caffae1248cd39305434e1dbf914527d /src
parentda5c5336a1eaf519de246f7d9f0f5585e1d4ac59 (diff)
downloadelfutils-2562759d6fe5b364fe224852e64e8bda39eb2e35.tar.gz
libdw: Check terminating NUL byte in dwarf_getsrclines for dir/file table.
For DWARF version < 5 the .debug_line directory and file tables consist of a terminating NUL byte after all strings. The code used to just skip this without checking it actually existed. This could case a spurious read past the end of data. Fix the same issue in readelf. https://sourceware.org/bugzilla/show_bug.cgi?id=24102 Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/readelf.c8
2 files changed, 11 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c0455f1c..4ad12a96 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-20 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_debug_line_section): Check terminating NUL byte
+ for dir and file tables.
+
2019-01-16 Mark Wielaard <mark@klomp.org>
* readelf (handle_core_note): Pass desc to ebl_core_note.
diff --git a/src/readelf.c b/src/readelf.c
index 71651e09..6bad3bfe 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8444,7 +8444,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
}
else
{
- while (*linep != 0)
+ while (linep < lineendp && *linep != 0)
{
unsigned char *endp = memchr (linep, '\0', lineendp - linep);
if (unlikely (endp == NULL))
@@ -8454,6 +8454,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
linep = endp + 1;
}
+ if (linep >= lineendp || *linep != 0)
+ goto invalid_unit;
/* Skip the final NUL byte. */
++linep;
}
@@ -8523,7 +8525,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
else
{
puts (gettext (" Entry Dir Time Size Name"));
- for (unsigned int cnt = 1; *linep != 0; ++cnt)
+ for (unsigned int cnt = 1; linep < lineendp && *linep != 0; ++cnt)
{
/* First comes the file name. */
char *fname = (char *) linep;
@@ -8553,6 +8555,8 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
printf (" %-5u %-5u %-9u %-9u %s\n",
cnt, diridx, mtime, fsize, fname);
}
+ if (linep >= lineendp || *linep != '\0')
+ goto invalid_unit;
/* Skip the final NUL byte. */
++linep;
}