[binutils-gdb] Move modification of bfd abs and und back to gas

Alan Modra amodra@sourceware.org
Sun Dec 15 23:35:28 GMT 2024


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

commit 35701ef3ea4a220d456d5ae1053a8630b24db388
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Dec 16 07:45:34 2024 +1030

    Move modification of bfd abs and und back to gas
    
    In commit f592407e4d75 I deleted gas' obj_sec_set_private_data, and
    instead put the gas modification of bfd's *ABS* and *UND* sections in
    bfd_make_section_old_way.  More recently in commit 8b5a21249537 I made
    tekhex symbol creation use bfd_make_section_old_way for symbol
    sections.  After that we saw numerous non-repeatable oss-fuzz reports
    of accesses to freed memory involving relocation symbols.  I think
    what is happening is:
    
    A tekhex testcase with an absolute symbol is run through the tool,
    modifying bfd_abs_section.symbol to point to a symbol on the bfd's
    objalloc memory.  On closing that bfd bfd_abs_section.symbol points to
    freed memory.
    
    A second testcase is run through the tool with some access to the
    *ABS* symbol.  This triggers the invalid memory access.
    
    The same thing could happen if a user runs objdump or nm with two
    files on the command line, the first being a tekhex file with absolute
    symbols, or if ld is given tekhex input among other files.  Clearly,
    it's a bad idea to modify the *ABS* or *UND* sections for input files.
    
    bfd/
            * section.c (bfd_make_section_old_way): Don't call
            _new_section_hook for standard abs, com, und and ind sections.
    gas/
            * as.c (bfd_std_section_init): New function.
            (perform_an_assembly_pass): Move section initialisation to..
            (gas_init): ..here.  Use bfd_std_section_init.

Diff:
---
 bfd/section.c |  5 -----
 gas/as.c      | 60 +++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/bfd/section.c b/bfd/section.c
index 07546a23c9d..9ed7a38fc61 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -1145,11 +1145,6 @@ bfd_make_section_old_way (bfd *abfd, const char *name)
       return bfd_section_init (abfd, newsect);
     }
 
-  /* Call new_section_hook when "creating" the standard abs, com, und
-     and ind sections to tack on format specific section data.
-     Also, create a proper section symbol.  */
-  if (! BFD_SEND (abfd, _new_section_hook, (abfd, newsect)))
-    return NULL;
   return newsect;
 }
 
diff --git a/gas/as.c b/gas/as.c
index f20b1e0cbe5..e629f30bf7b 100644
--- a/gas/as.c
+++ b/gas/as.c
@@ -1176,35 +1176,9 @@ static void
 perform_an_assembly_pass (int argc, char ** argv)
 {
   int saw_a_file = 0;
-#ifndef OBJ_MACH_O
-  flagword applicable;
-#endif
 
   need_pass_2 = 0;
 
-#ifndef OBJ_MACH_O
-  /* Create the standard sections, and those the assembler uses
-     internally.  */
-  text_section = subseg_new (TEXT_SECTION_NAME, 0);
-  data_section = subseg_new (DATA_SECTION_NAME, 0);
-  bss_section = subseg_new (BSS_SECTION_NAME, 0);
-  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
-     to have relocs, otherwise we don't find out in time.  */
-  applicable = bfd_applicable_section_flags (stdoutput);
-  bfd_set_section_flags (text_section,
-			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
-				       | SEC_CODE | SEC_READONLY));
-  bfd_set_section_flags (data_section,
-			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
-				       | SEC_DATA));
-  bfd_set_section_flags (bss_section, applicable & SEC_ALLOC);
-  seg_info (bss_section)->bss = 1;
-#endif
-  subseg_new (BFD_ABS_SECTION_NAME, 0);
-  subseg_new (BFD_UND_SECTION_NAME, 0);
-  reg_section = subseg_new ("*GAS `reg' section*", 0);
-  expr_section = subseg_new ("*GAS `expr' section*", 0);
-
 #ifndef OBJ_MACH_O
   subseg_set (text_section, 0);
 #endif
@@ -1292,6 +1266,17 @@ gas_early_init (int *argcp, char ***argvp)
 #endif
 }
 
+/* Tack on format specific section data and create a proper section
+   symbol for one of the standard bfd sections.  */
+
+static void
+bfd_std_section_init (const char *name)
+{
+  asection *sec = bfd_make_section_old_way (stdoutput, name);
+  gas_assert (BFD_SEND (stdoutput, _new_section_hook, (stdoutput, sec)));
+  subseg_new (name, 0);
+}
+
 /* The bulk of gas initialisation.  This is after args are parsed.  */
 
 static void
@@ -1353,6 +1338,29 @@ gas_init (void)
       free (defsyms);
       defsyms = next;
     }
+
+#ifndef OBJ_MACH_O
+  /* Create the standard sections, and those the assembler uses
+     internally.  */
+  text_section = subseg_new (TEXT_SECTION_NAME, 0);
+  data_section = subseg_new (DATA_SECTION_NAME, 0);
+  bss_section = subseg_new (BSS_SECTION_NAME, 0);
+  /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
+     to have relocs, otherwise we don't find out in time.  */
+  flagword applicable = bfd_applicable_section_flags (stdoutput);
+  bfd_set_section_flags (text_section,
+			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+				       | SEC_CODE | SEC_READONLY));
+  bfd_set_section_flags (data_section,
+			 applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+				       | SEC_DATA));
+  bfd_set_section_flags (bss_section, applicable & SEC_ALLOC);
+  seg_info (bss_section)->bss = 1;
+#endif
+  bfd_std_section_init (BFD_ABS_SECTION_NAME);
+  bfd_std_section_init (BFD_UND_SECTION_NAME);
+  reg_section = subseg_new ("*GAS `reg' section*", 0);
+  expr_section = subseg_new ("*GAS `expr' section*", 0);
 }
 
 int


More information about the Binutils-cvs mailing list