]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 33302, Symbols truncated on i386pep target
authorAlan Modra <amodra@gmail.com>
Sat, 23 Aug 2025 03:37:40 +0000 (13:07 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 24 Aug 2025 22:58:38 +0000 (08:28 +0930)
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>
bfd/coffswap.h
bfd/peXXigen.c
gas/testsuite/gas/pe/long_file_symbol.d [new file with mode: 0644]
gas/testsuite/gas/pe/long_file_symbol.s [new file with mode: 0644]
gas/testsuite/gas/pe/pe.exp
include/coff/external.h

index 4d63824f3d7e458dc31bd8b3caf7274c3e71d6d3..823d3fd9e6599624ba4ef8ee820de98d872cef26 100644 (file)
@@ -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:
index c337fc5b28205336dc4b733b2190a2ab1999e789..1a195d97c5c07809daf57a164797675092b51741 100644 (file)
@@ -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 (file)
index 0000000..43510b9
--- /dev/null
@@ -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 (file)
index 0000000..066499f
--- /dev/null
@@ -0,0 +1 @@
+ .file "long_file_symbol.s"
index 00a6d14fbfae4c75ece927f141855dfd4fd3f446..8682789d209a9288e19f7c844fc733d21b3076e1 100644 (file)
@@ -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"
index 91c5dac5af191c94c105a23e3f27ecaa4dc31842..1b3c06db2ebe8d7e85d32c5eaecf51dedfd94d73 100644 (file)
@@ -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
     {