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.
This commit is contained in:
Alan Modra
2020-12-15 21:54:09 +10:30
parent 9f132af9e1
commit 7bed846687
4 changed files with 34 additions and 8 deletions

View 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> 2020-12-14 Alan Modra <amodra@gmail.com>
* testsuite/gas/elf/section27.s: Reorder .text, .data and .bss * testsuite/gas/elf/section27.s: Reorder .text, .data and .bss

View File

@ -2102,6 +2102,22 @@ elf_obj_symbol_new_hook (symbolS *symbolP)
#endif #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 /* When setting one symbol equal to another, by default we probably
want them to have the same "size", whatever it means in the current want them to have the same "size", whatever it means in the current
context. */ context. */
@ -3088,6 +3104,6 @@ const struct format_ops elf_format_ops =
#endif #endif
elf_obj_read_begin_hook, elf_obj_read_begin_hook,
elf_obj_symbol_new_hook, elf_obj_symbol_new_hook,
0, elf_obj_symbol_clone_hook,
elf_adjust_symtab elf_adjust_symtab
}; };

View File

@ -223,6 +223,11 @@ void elf_obj_symbol_new_hook (symbolS *);
#define obj_symbol_new_hook elf_obj_symbol_new_hook #define obj_symbol_new_hook elf_obj_symbol_new_hook
#endif #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 *); void elf_copy_symbol_attributes (symbolS *, symbolS *);
#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES #ifndef OBJ_COPY_SYMBOL_ATTRIBUTES
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \ #define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \

View File

@ -508,17 +508,12 @@ buffer_line (file_info_type *file, char *line, unsigned int size)
fseek (last_open_file, file->pos, SEEK_SET); fseek (last_open_file, file->pos, SEEK_SET);
} }
/* Leave room for null. */
size -= 1;
c = fgetc (last_open_file); c = fgetc (last_open_file);
while (c != EOF && c != '\n' && c != '\r') while (c != EOF && c != '\n' && c != '\r')
{ {
if (count < size) if (++count < size)
*p++ = c; *p++ = c;
count++;
c = fgetc (last_open_file); c = fgetc (last_open_file);
} }
@ -536,7 +531,7 @@ buffer_line (file_info_type *file, char *line, unsigned int size)
if (c == EOF) if (c == EOF)
{ {
file->at_end = 1; file->at_end = 1;
if (count + 2 < size) if (count + 3 < size)
{ {
*p++ = '.'; *p++ = '.';
*p++ = '.'; *p++ = '.';