[binutils-gdb] PR 33302, Symbols truncated on i386pep target

Alan Modra amodra@sourceware.org
Sun Aug 24 22:59:17 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6274233ac8dddf923f567227dd887e1d79bf35d7

commit 6274233ac8dddf923f567227dd887e1d79bf35d7
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Aug 23 13:07:40 2025 +0930

    PR 33302, Symbols truncated on i386pep target
    
    Commit 012d44268695 effectively made peXXigen.c _bfd_XXi_swap_aux_out
    always use the COFF E_FILNMLEN of 14.  The problem was that the auxent
    x_fname field was defined in include/coff/external.h using a length of
    14.  Later, E_FILNMLEN is redefined to 18 in coff/pe.h.  This no doubt
    falsely tripped memory checking tools.  AUXESZ is 18, so no actual
    buffer overrun.
    
    This patch defines x_fname as an 18 char field, the full auxent, and
    uses E_FILNMLEN when accessing.
    
            PR 33302
    include/
            * coff/external.h (union external_auxent): Make x_fname
            AUXESZ chars.
    bfd/
            * coffswap.h (coff_swap_aux_in): Correct #error message.
            (coff_swap_aux_out): Likewise.  Use E_FILNMLEN when copying
            to ext field.
            * peXXigen.c (_bfd_XXi_swap_aux_in): Add #error.  Style fix.
            (_bfd_XXi_swap_aux_out): Add #error.  Don't use sizeof, use
            E_FILNMLEN when copying to ext field.
    gas
            * testsuite/gas/pe/long_file_symbol.d,
            * testsuite/gas/pe/long_file_symbol.s: New test.
            * testsuite/gas/pe/pe.exp: Run it.
    
    Reported-By: Frediano Ziglio <freddy77@gmail.com>

Diff:
---
 bfd/coffswap.h                          | 14 ++++----------
 bfd/peXXigen.c                          | 10 ++++++++--
 gas/testsuite/gas/pe/long_file_symbol.d |  5 +++++
 gas/testsuite/gas/pe/long_file_symbol.s |  1 +
 gas/testsuite/gas/pe/pe.exp             |  2 +-
 include/coff/external.h                 |  5 ++++-
 6 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/bfd/coffswap.h b/bfd/coffswap.h
index 4d63824f3d7..823d3fd9e65 100644
--- a/bfd/coffswap.h
+++ b/bfd/coffswap.h
@@ -422,13 +422,10 @@ coff_swap_aux_in (bfd *abfd,
 	  in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
 	}
       else
-	{
 #if FILNMLEN != E_FILNMLEN
-#error we need to cope with truncating or extending FILNMLEN
-#else
-	  memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
+#error we need to cope with truncating or extending x_fname
 #endif
-	}
+	memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
       goto end;
 
     case C_STAT:
@@ -521,13 +518,10 @@ coff_swap_aux_out (bfd * abfd,
 	  H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
 	}
       else
-	{
 #if FILNMLEN != E_FILNMLEN
-#error we need to cope with truncating or extending FILNMLEN
-#else
-	  memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, FILNMLEN);
+#error we need to cope with truncating or extending xfname
 #endif
-	}
+	memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN);
       goto end;
 
     case C_STAT:
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c337fc5b282..1a195d97c5c 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -289,7 +289,7 @@ _bfd_XXi_swap_aux_in (bfd *	abfd,
 
   /* PR 17521: Make sure that all fields in the aux structure
      are initialised.  */
-  memset (in, 0, sizeof * in);
+  memset (in, 0, sizeof (*in));
   switch (in_class)
     {
     case C_FILE:
@@ -299,6 +299,9 @@ _bfd_XXi_swap_aux_in (bfd *	abfd,
 	  in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
 	}
       else
+#if FILNMLEN != E_FILNMLEN
+#error we need to cope with truncating or extending x_fname
+#endif
 	memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
       return;
 
@@ -373,7 +376,10 @@ _bfd_XXi_swap_aux_out (bfd *  abfd,
 	  H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
 	}
       else
-	memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, sizeof (ext->x_file.x_fname));
+#if FILNMLEN != E_FILNMLEN
+#error we need to cope with truncating or extending x_fname
+#endif
+	memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN);
 
       return AUXESZ;
 
diff --git a/gas/testsuite/gas/pe/long_file_symbol.d b/gas/testsuite/gas/pe/long_file_symbol.d
new file mode 100644
index 00000000000..43510b98df7
--- /dev/null
+++ b/gas/testsuite/gas/pe/long_file_symbol.d
@@ -0,0 +1,5 @@
+#nm: -a
+
+#...
+.* long_file_symbol.s
+#pass
diff --git a/gas/testsuite/gas/pe/long_file_symbol.s b/gas/testsuite/gas/pe/long_file_symbol.s
new file mode 100644
index 00000000000..066499fefba
--- /dev/null
+++ b/gas/testsuite/gas/pe/long_file_symbol.s
@@ -0,0 +1 @@
+ .file "long_file_symbol.s"
diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp
index 00a6d14fbfa..8682789d209 100644
--- a/gas/testsuite/gas/pe/pe.exp
+++ b/gas/testsuite/gas/pe/pe.exp
@@ -31,7 +31,7 @@ run_dump_test "aligncomm-a"
 run_dump_test "aligncomm-b"
 run_dump_test "aligncomm-c"
 run_dump_test "aligncomm-d"
-
+run_dump_test "long_file_symbol"
 run_dump_test "section-align-1"
 run_dump_test "section-align-3"
 run_dump_test "section-exclude"
diff --git a/include/coff/external.h b/include/coff/external.h
index 91c5dac5af1..1b3c06db2eb 100644
--- a/include/coff/external.h
+++ b/include/coff/external.h
@@ -223,7 +223,10 @@ typedef union external_auxent
 
   union
   {
-    char x_fname[E_FILNMLEN];
+    /* Make x_fname the full auxent size, so that if coff/pe.h
+       redefines E_FILNMLEN from 14 to 18 we don't trigger sanitisers
+       accessing x_fname.  Beware use of sizeof (x_file.x_fname).  */
+    char x_fname[AUXESZ];
 
     struct
     {


More information about the Binutils-cvs mailing list