diff options
author | Alan Modra <amodra@gmail.com> | 2020-12-15 21:54:09 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-12-16 01:13:58 +1030 |
commit | 7bed846687589e1346626e8bc9f2948340ef454b (patch) | |
tree | 4b656167da9efec90ae7711faf78e32f36762099 /gas | |
parent | 9f132af9e189a6c1e90b1ab7ed84c6613c8ac596 (diff) | |
download | gdb-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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/config/obj-elf.c | 18 | ||||
-rw-r--r-- | gas/config/obj-elf.h | 5 | ||||
-rw-r--r-- | gas/listing.c | 9 |
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++ = '.'; |