Subject: Verify COFF symbol stringtab offset
From: Keith Seitz <keiths@...>
Date: Wed, 2 Aug 2023 15:35:11 +0000 (-0700)

Verify COFF symbol stringtab offset

This patch addresses an issue with malformed/fuzzed debug information that
was recently reported in gdb/30639. That bug specifically deals with
an ASAN issue, but the reproducer provided by the reporter causes a
another failure outside of ASAN:

Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=58abdf887821a5da09ba184c6e400a3bc5cccd5a]

CVE: CVE-2023-39129

Signed-off-by: Deepthi Hemraj <[email-masked]>

diff --git a/gdb/coffread.c b/gdb/coffread.c
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -159,6 +160,7 @@ static file_ptr linetab_offset;
 static file_ptr linetab_size;
 
 static char *stringtab = NULL;
+static long stringtab_length = 0;
 
 extern void stabsread_clear_cache (void);
 
@@ -1303,6 +1298,7 @@ init_stringtab (bfd *abfd, file_ptr offset, gdb::unique_xmalloc_ptr<char> *stora
   /* This is in target format (probably not very useful, and not
      currently used), not host format.  */
   memcpy (stringtab, lengthbuf, sizeof lengthbuf);
+  stringtab_length = length;
   if (length == sizeof length)	/* Empty table -- just the count.  */
     return 0;
 
@@ -1322,8 +1318,9 @@ getsymname (struct internal_syment *symbol_entry)
 
   if (symbol_entry->_n._n_n._n_zeroes == 0)
     {
-      /* FIXME: Probably should be detecting corrupt symbol files by
-	 seeing whether offset points to within the stringtab.  */
+      if (symbol_entry->_n._n_n._n_offset > stringtab_length)
+	error (_("COFF Error: string table offset (%ld) outside string table (length %ld)"),
+	       symbol_entry->_n._n_n._n_offset, stringtab_length);
       result = stringtab + symbol_entry->_n._n_n._n_offset;
     }
   else