aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2025-08-23 13:07:40 +0930
committerAlan Modra <amodra@gmail.com>2025-08-25 08:28:38 +0930
commit6274233ac8dddf923f567227dd887e1d79bf35d7 (patch)
treeb24511a6e582fa31eba19e70611eefe25d3b8c8d
parent5db3a9f674fd8e447f7bdfd8686f9dccf2b35ea6 (diff)
downloadbinutils-6274233ac8dddf923f567227dd887e1d79bf35d7.zip
binutils-6274233ac8dddf923f567227dd887e1d79bf35d7.tar.gz
binutils-6274233ac8dddf923f567227dd887e1d79bf35d7.tar.bz2
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>
-rw-r--r--bfd/coffswap.h14
-rw-r--r--bfd/peXXigen.c10
-rw-r--r--gas/testsuite/gas/pe/long_file_symbol.d5
-rw-r--r--gas/testsuite/gas/pe/long_file_symbol.s1
-rw-r--r--gas/testsuite/gas/pe/pe.exp2
-rw-r--r--include/coff/external.h5
6 files changed, 23 insertions, 14 deletions
diff --git a/bfd/coffswap.h b/bfd/coffswap.h
index 4d63824..823d3fd 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 c337fc5..1a195d9 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 0000000..43510b9
--- /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 0000000..066499f
--- /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 00a6d14..8682789 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 91c5dac..1b3c06d 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
{