diff options
author | Alan Modra <amodra@gmail.com> | 2025-08-23 13:07:40 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-08-25 08:28:38 +0930 |
commit | 6274233ac8dddf923f567227dd887e1d79bf35d7 (patch) | |
tree | b24511a6e582fa31eba19e70611eefe25d3b8c8d | |
parent | 5db3a9f674fd8e447f7bdfd8686f9dccf2b35ea6 (diff) | |
download | binutils-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.h | 14 | ||||
-rw-r--r-- | bfd/peXXigen.c | 10 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/long_file_symbol.d | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/long_file_symbol.s | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/pe/pe.exp | 2 | ||||
-rw-r--r-- | include/coff/external.h | 5 |
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 { |