[binutils-gdb] gdb/ada: avoid rereading stale main name data in edge case

Andrew Burgess via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7800332405e135eaf3e1482b8195669b3662c142

commit 7800332405e135eaf3e1482b8195669b3662c142
Author: Andrew Burgess <[email protected]>
Date:   Wed Aug 5 17:23:38 2026 +0100

    gdb/ada: avoid rereading stale main name data in edge case
    
    The commit:
    
      commit 8eafbbc74748e499ec785f78858687bd7ea79005
      Date:   Wed Jul 29 12:40:03 2026 -0600
    
        Always fetch Ada "main" name from the executable
    
    changes ada_main_name to use section_table_xfer_memory_partial.  This
    introduced a highly unlikely, but theoretical bug where stale buffer
    data could cause GDB to find an invalid name for "main".
    
    Looking at ada_main_name (in ada-lang.c), the steps to reproduce the
    bug are:
    
      1. Debug a program that causes the static buffer main_program_name
         to have some content written to it.  For the sake of this bug
         let's assume the main name is "xxxxxxxxxx", the main_program_name
         buffer will contain 10 'x' characters, a null byte, then whatever
         happened to be in the section after that.
    
      2. A new executable is loaded into GDB and ada_main_name is called
         again.
    
      3. For whatever reason the new executable is maybe not correct.  The
         ADA_MAIN_PROGRAM_SYMBOL_NAME symbol points to an address 5 bytes
         before the end of a section.  None of these 5 bytes are a null
         bytes.  Let's assume these 5 bytes are "aaaaa".
    
      4. The section_table_xfer_memory_partial call will try to read up to
         1024 bytes, but as there are only 5 bytes left in the section,
         only 5 will be read.  This leaves the main_program_name buffer
         containing "aaaaaxxxxx" followed by a null character byte.
    
      5. GDB returns this merged string as the result from ada_main_name.
    
    Now given this depends on the second executable being broken, we maybe
    don't really care too much, however, fixing this is pretty easy.
    
    The current code already checks:
    
      && (strnlen ((char *) main_program_name, sizeof (main_program_name))
          < sizeof (main_program_name))
    
    This ensures that there's a string with a null byte contained within
    the buffer, but makes the assumption that we always read
    sizeof (main_program_name) bytes from the section.
    
    But we know how many bytes were read, that's the value in XFERRED.
    What we really want to ask is: was there a null terminated string
    within the bytes that we just read.  This is:
    
      && (strnlen ((char *) main_program_name, xferred) < xferred)
    
    Given how simple this fix is, let's make it.
    
    Approved-By: Tom Tromey <[email protected]>

Diff:
---
 gdb/ada-lang.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 906c5cd3465..174e04af04c 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -806,8 +806,7 @@ ada_main_name ()
 					      sections)
 	   == TARGET_XFER_OK)
 	  && xferred > 0
-	  && (strnlen ((char *) main_program_name, sizeof (main_program_name))
-	      < sizeof (main_program_name)))
+	  && (strnlen ((char *) main_program_name, xferred) < xferred))
 	return (char *) main_program_name;
     }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.