diff options
author | Nick Clifton <nickc@redhat.com> | 2020-09-09 15:54:20 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-09-09 15:54:20 +0100 |
commit | ad2a37157d3476dffb3baf93ca5001c9f6c44bda (patch) | |
tree | 8d0820d582070a50354f4c873fb0704914e9c0b7 /lto-plugin | |
parent | 5d3c12e4184a5e8d0cfda41e90bb2fcd98e7ddae (diff) | |
download | gcc-ad2a37157d3476dffb3baf93ca5001c9f6c44bda.zip gcc-ad2a37157d3476dffb3baf93ca5001c9f6c44bda.tar.gz gcc-ad2a37157d3476dffb3baf93ca5001c9f6c44bda.tar.bz2 |
If the lto plugin encounters a file with multiple symbol sections, each of which also has a v1 symbol extension section[1] then it will attempt to read the extension data for *every* symbol from each of the extension sections. This results in reading off the end of a buffer with the associated memory corruption that that entails. This patch fixes that problem.
2020-09-09 Nick Clifton <nickc@redhat.com>
* lto-plugin.c (struct plugin_symtab): Add last_sym field.
(parse_symtab_extension): Only read as many entries as are
available in the buffer. Store the data read into the symbol
table indexed from last_sym. Increment last_sym.
Diffstat (limited to 'lto-plugin')
-rw-r--r-- | lto-plugin/lto-plugin.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c index a65c280..6f67552 100644 --- a/lto-plugin/lto-plugin.c +++ b/lto-plugin/lto-plugin.c @@ -115,6 +115,7 @@ struct sym_aux struct plugin_symtab { int nsyms; + int last_sym; struct sym_aux *aux; struct ld_plugin_symbol *syms; unsigned long long id; @@ -382,19 +383,30 @@ translate (char *data, char *end, struct plugin_symtab *out) static void parse_symtab_extension (char *data, char *end, struct plugin_symtab *out) { - unsigned i; + unsigned long i; + unsigned char version; + + if (data >= end) + /* FIXME: Issue an error ? */ + return; - unsigned char version = *data; + version = *data; data++; + if (version != 1) + return; + /* Version 1 contains the following data per entry: - symbol_type - section_kind . */ - if (version == 1) - for (i = 0; i < out->nsyms; i++) - data = parse_table_entry_extension (data, &out->syms[i]); + unsigned long nsyms = (end - data) / 2; + + for (i = 0; i < nsyms; i++) + data = parse_table_entry_extension (data, out->syms + i + out->last_sym); + + out->last_sym += nsyms; } /* Free all memory that is no longer needed after writing the symbol @@ -1172,9 +1184,12 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed) /* Parsing symtab extension should be done only for add_symbols_v2 and later versions. */ if (!errmsg && add_symbols_v2 != NULL) - errmsg = simple_object_find_sections (obj.objfile, - process_symtab_extension, - &obj, &err); + { + obj.out->last_sym = 0; + errmsg = simple_object_find_sections (obj.objfile, + process_symtab_extension, + &obj, &err); + } } if (!obj.objfile || errmsg) |