aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-12-15 21:54:09 +1030
committerAlan Modra <amodra@gmail.com>2020-12-16 01:13:58 +1030
commit7bed846687589e1346626e8bc9f2948340ef454b (patch)
tree4b656167da9efec90ae7711faf78e32f36762099
parent9f132af9e189a6c1e90b1ab7ed84c6613c8ac596 (diff)
downloadgdb-7bed846687589e1346626e8bc9f2948340ef454b.zip
gdb-7bed846687589e1346626e8bc9f2948340ef454b.tar.gz
gdb-7bed846687589e1346626e8bc9f2948340ef454b.tar.bz2
PR27071, gas bugs uncovered by fuzzing
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.
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/obj-elf.c18
-rw-r--r--gas/config/obj-elf.h5
-rw-r--r--gas/listing.c9
4 files changed, 34 insertions, 8 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d74fed1..1a6c85a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 5d3b1a0..bee95c3 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -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
};
diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h
index c714ba7..951109e 100644
--- a/gas/config/obj-elf.h
+++ b/gas/config/obj-elf.h
@@ -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) \
diff --git a/gas/listing.c b/gas/listing.c
index 359dc09..bf38c1a 100644
--- a/gas/listing.c
+++ b/gas/listing.c
@@ -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++ = '.';