som_bfd_fill_in_ar_symbols buffer overflow
authorAlan Modra <amodra@gmail.com>
Mon, 6 Jan 2020 06:42:51 +0000 (17:12 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 6 Jan 2020 11:23:51 +0000 (21:53 +1030)
* som.c (som_bfd_fill_in_ar_symbols): Bounds check som_dict index.

bfd/ChangeLog
bfd/som.c

index 1d2b346060c9f3042e73576b786ec26b51e91baa..2aed0db7ac20a227857c982dfcc48ac73150a0ec 100644 (file)
@@ -1,3 +1,7 @@
+2020-01-06  Alan Modra  <amodra@gmail.com>
+
+       * som.c (som_bfd_fill_in_ar_symbols): Bounds check som_dict index.
+
 2020-01-06  Alan Modra  <amodra@gmail.com>
 
        * mach-o.c (bfd_mach_o_read_dylinker): Don't read past end of
index 954b75213ea59e0c6f719f50f67671fe26854c54..779fd5d3883a1a5c87254bdaae10f5fcebb2d706 100644 (file)
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -6002,6 +6002,7 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
       size_t len;
       unsigned char ext_len[4];
       char *name;
+      unsigned int ndx;
 
       /* An empty chain has zero as it's file offset.  */
       hash_val = bfd_getb32 (hash_table + 4 * i);
@@ -6048,9 +6049,14 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
 
       /* Fill in the file offset.  Note that the "location" field points
         to the SOM itself, not the ar_hdr in front of it.  */
-      set->file_offset =
-       bfd_getb32 (som_dict[bfd_getb32 (lst_symbol.som_index)].location)
-       - sizeof (struct ar_hdr);
+      ndx = bfd_getb32 (lst_symbol.som_index);
+      if (ndx >= lst_header->module_count)
+       {
+         bfd_set_error (bfd_error_bad_value);
+         goto error_return;
+       }
+      set->file_offset
+       = bfd_getb32 (som_dict[ndx].location) - sizeof (struct ar_hdr);
 
       /* Go to the next symbol.  */
       set++;
@@ -6097,9 +6103,14 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
 
          /* Fill in the file offset.  Note that the "location" field points
             to the SOM itself, not the ar_hdr in front of it.  */
-         set->file_offset =
-           bfd_getb32 (som_dict[bfd_getb32 (lst_symbol.som_index)].location)
-           - sizeof (struct ar_hdr);
+         ndx = bfd_getb32 (lst_symbol.som_index);
+         if (ndx >= lst_header->module_count)
+           {
+             bfd_set_error (bfd_error_bad_value);
+             goto error_return;
+           }
+         set->file_offset
+           = bfd_getb32 (som_dict[ndx].location) - sizeof (struct ar_hdr);
 
          /* Go on to the next symbol.  */
          set++;