objcopy section alignment
authorAlan Modra <amodra@gmail.com>
Sat, 6 Aug 2022 05:27:27 +0000 (14:57 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 6 Aug 2022 09:13:24 +0000 (18:43 +0930)
bfd_set_section_alignment currently always returns true.  This patch
changes it to return false on silly alignment values, avoiding yet
another way to trigger ubsan errors like coffcode.h:3192:12: runtime
error: shift exponent 299 is too large for 32-bit type 'int'.  We'll
catch that one in objcopy.c:setup_sections.  However, setup_sections
gives up on other setup operations that are necessary even after an
error of some sort.  Change that to keep going, which might change the
error message but that shouldn't matter in the least.

bfd/
* section.c (bfd_set_section_alignment): Return false and
don't set alignment_power for stupidly large alignments.
* bfd-in2.h: Regenerate.
* coffcode.h (coff_compute_section_file_positions): Don't use
an int constant when calculating alignment.
binutils/
* objcopy.c (setup_section): Keep on going after hitting
non-fatal errors.

bfd/bfd-in2.h
bfd/coffcode.h
bfd/section.c
binutils/objcopy.c

index 0d2e915b413e0d3656875519d1c75b8fb9bb0747..4ab7e2d69347fc8d707094c18b29e1b32ecfcd69 100644 (file)
@@ -1201,6 +1201,8 @@ bfd_set_section_lma (asection *sec, bfd_vma val)
 static inline bool
 bfd_set_section_alignment (asection *sec, unsigned int val)
 {
+  if (val >= sizeof (bfd_vma) * 8 - 1)
+    return false;
   sec->alignment_power = val;
   return true;
 }
index 0dc68a9a25fb9fcfeb18e669c594b97221ea76e4..798b9f249b51106b44dfd8fbb9a6ea6327d9abe5 100644 (file)
@@ -3189,7 +3189,7 @@ coff_compute_section_file_positions (bfd * abfd)
 #ifdef COFF_IMAGE_WITH_PE
          sofar = BFD_ALIGN (sofar, page_size);
 #else
-         sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+         sofar = BFD_ALIGN (sofar, (bfd_vma) 1 << current->alignment_power);
 #endif
 
 #ifdef RS6000COFF_C
@@ -3259,7 +3259,7 @@ coff_compute_section_file_positions (bfd * abfd)
 
          old_size = current->size;
          current->size = BFD_ALIGN (current->size,
-                                    1 << current->alignment_power);
+                                    (bfd_vma) 1 << current->alignment_power);
          align_adjust = current->size != old_size;
          sofar += current->size - old_size;
        }
@@ -3269,7 +3269,7 @@ coff_compute_section_file_positions (bfd * abfd)
 #ifdef COFF_IMAGE_WITH_PE
          sofar = BFD_ALIGN (sofar, page_size);
 #else
-         sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
+         sofar = BFD_ALIGN (sofar, (bfd_vma) 1 << current->alignment_power);
 #endif
          align_adjust = sofar != old_sofar;
          current->size += sofar - old_sofar;
@@ -3315,7 +3315,8 @@ coff_compute_section_file_positions (bfd * abfd)
   /* Make sure the relocations are aligned.  We don't need to make
      sure that this byte exists, because it will only matter if there
      really are relocs.  */
-  sofar = BFD_ALIGN (sofar, 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
+  sofar = BFD_ALIGN (sofar,
+                    (bfd_vma) 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
 
   obj_relocbase (abfd) = sofar;
   abfd->output_has_begun = true;
index 5a487ce6c6f8e370a6df008f7d3478117642b6e5..c7a02d729f26965148ece9478346b14e6c8c7fb1 100644 (file)
@@ -631,6 +631,8 @@ CODE_FRAGMENT
 .static inline bool
 .bfd_set_section_alignment (asection *sec, unsigned int val)
 .{
+.  if (val >= sizeof (bfd_vma) * 8 - 1)
+.    return false;
 .  sec->alignment_power = val;
 .  return true;
 .}
index 21c3a7127c87b684799badfc6b401c2154c04454..b907b02d5e7483dcf7915e02f930cfc468a47d9c 100644 (file)
@@ -4014,7 +4014,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   bfd_vma vma;
   bfd_vma lma;
   flagword flags;
-  const char *err;
+  const char *err = NULL;
   const char * name;
   const char * new_name;
   char *prefix = NULL;
@@ -4097,10 +4097,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   else if (extract_symbol)
     size = 0;
   if (!bfd_set_section_size (osection, size))
-    {
-      err = _("failed to set size");
-      goto loser;
-    }
+    err = _("failed to set size");
 
   vma = bfd_section_vma (isection);
   p = find_section_list (bfd_section_name (isection), false,
@@ -4116,10 +4113,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
     vma += change_section_address;
 
   if (!bfd_set_section_vma (osection, vma))
-    {
-      err = _("failed to set vma");
-      goto loser;
-    }
+    err = _("failed to set vma");
 
   lma = isection->lma;
   p = find_section_list (bfd_section_name (isection), false,
@@ -4146,10 +4140,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   /* FIXME: This is probably not enough.  If we change the LMA we
      may have to recompute the header for the file as well.  */
   if (!bfd_set_section_alignment (osection, alignment))
-    {
-      err = _("failed to set alignment");
-      goto loser;
-    }
+    err = _("failed to set alignment");
 
   /* Copy merge entity size.  */
   osection->entsize = isection->entsize;
@@ -4178,16 +4169,13 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
   /* Allow the BFD backend to copy any private data it understands
      from the input section to the output section.  */
   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
-    {
-      err = _("failed to copy private data");
-      goto loser;
-    }
+    err = _("failed to copy private data");
 
   if (make_nobits)
     elf_section_type (osection) = SHT_NOBITS;
 
-  /* All went well.  */
-  return;
+  if (!err)
+    return;
 
  loser:
   status = 1;