PR27071, gas bugs uncovered by fuzzing
authorAlan Modra <amodra@gmail.com>
Tue, 15 Dec 2020 11:24:09 +0000 (21:54 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 15 Dec 2020 14:43:58 +0000 (01:13 +1030)
PR 27071
* config/obj-elf.c (elf_obj_symbol_clone_hook): New function.
(elf_format_ops): Set symbol_clone_hook.
* config/obj-elf.h (elf_obj_symbol_clone_hook): Declare.
(obj_symbol_clone_hook): Define.
* listing.c (buffer_line): Avoid integer overflow on paper_width
set to zero.

gas/ChangeLog
gas/config/obj-elf.c
gas/config/obj-elf.h
gas/listing.c

index d74fed131dffbfbb7210754852b52f8e84099d35..1a6c85a46992ed09eed72488d076c46319eddb2a 100644 (file)
@@ -1,3 +1,13 @@
+2020-12-15  Alan Modra  <amodra@gmail.com>
+
+       PR 27071
+       * config/obj-elf.c (elf_obj_symbol_clone_hook): New function.
+       (elf_format_ops): Set symbol_clone_hook.
+       * config/obj-elf.h (elf_obj_symbol_clone_hook): Declare.
+       (obj_symbol_clone_hook): Define.
+       * listing.c (buffer_line): Avoid integer overflow on paper_width
+       set to zero.
+
 2020-12-14  Alan Modra  <amodra@gmail.com>
 
        * testsuite/gas/elf/section27.s: Reorder .text, .data and .bss
index 5d3b1a0edc4f8742bf3a9a49072b7c459e320726..bee95c3f0f5c5e3e20c16c3e0ed81234c7a22386 100644 (file)
@@ -2102,6 +2102,22 @@ elf_obj_symbol_new_hook (symbolS *symbolP)
 #endif
 }
 
+/* Deduplicate size expressions.  We might get into trouble with
+   multiple freeing or use after free if we leave them pointing to the
+   same expressionS.  */
+
+void
+elf_obj_symbol_clone_hook (symbolS *newsym, symbolS *orgsym ATTRIBUTE_UNUSED)
+{
+  struct elf_obj_sy *newelf = symbol_get_obj (newsym);
+  if (newelf->size)
+    {
+      expressionS *exp = XNEW (expressionS);
+      *exp = *newelf->size;
+      newelf->size = exp;
+    }
+}
+
 /* When setting one symbol equal to another, by default we probably
    want them to have the same "size", whatever it means in the current
    context.  */
@@ -3088,6 +3104,6 @@ const struct format_ops elf_format_ops =
 #endif
   elf_obj_read_begin_hook,
   elf_obj_symbol_new_hook,
-  0,
+  elf_obj_symbol_clone_hook,
   elf_adjust_symtab
 };
index c714ba7a7088d8afc1eba2582b2c47b52caea485..951109ee4207961eb5e7ed5943a11506e50adb90 100644 (file)
@@ -223,6 +223,11 @@ void elf_obj_symbol_new_hook (symbolS *);
 #define obj_symbol_new_hook    elf_obj_symbol_new_hook
 #endif
 
+void elf_obj_symbol_clone_hook (symbolS *, symbolS *);
+#ifndef obj_symbol_clone_hook
+#define obj_symbol_clone_hook  elf_obj_symbol_clone_hook
+#endif
+
 void elf_copy_symbol_attributes (symbolS *, symbolS *);
 #ifndef OBJ_COPY_SYMBOL_ATTRIBUTES
 #define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
index 359dc090dc0df6115bfebae0b63eb6a1827aca03..bf38c1ae9c268a4663f2672bea7e632865c46ac3 100644 (file)
@@ -508,17 +508,12 @@ buffer_line (file_info_type *file, char *line, unsigned int size)
        fseek (last_open_file, file->pos, SEEK_SET);
     }
 
-  /* Leave room for null.  */
-  size -= 1;
-
   c = fgetc (last_open_file);
 
   while (c != EOF && c != '\n' && c != '\r')
     {
-      if (count < size)
+      if (++count < size)
        *p++ = c;
-      count++;
-
       c = fgetc (last_open_file);
     }
 
@@ -536,7 +531,7 @@ buffer_line (file_info_type *file, char *line, unsigned int size)
   if (c == EOF)
     {
       file->at_end = 1;
-      if (count + 2 < size)
+      if (count + 3 < size)
        {
          *p++ = '.';
          *p++ = '.';