diff options
author | Alan Modra <amodra@gmail.com> | 2023-04-24 11:19:15 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-04-24 20:59:38 +0930 |
commit | 2043ddb2185096eadc111865f31a70d1cffd6f4c (patch) | |
tree | a3a94741037461f71651abb7d1a3a2f6f559228f | |
parent | c1eb3cd205921fb7af668f2032ab2c7142c4f24c (diff) | |
download | binutils-2043ddb2185096eadc111865f31a70d1cffd6f4c.zip binutils-2043ddb2185096eadc111865f31a70d1cffd6f4c.tar.gz binutils-2043ddb2185096eadc111865f31a70d1cffd6f4c.tar.bz2 |
asan: segfault in coff_mangle_symbols
The testcase managed to trigger creation of a wild pointer in
coff_slurp_symbol_table. Stop that happening, and fix an unrelated
problem I happened to see in bfd_coff_get_syment.
* coff-bfd.c (bfd_coff_get_syment): Clear fix_value after
converting n_value from a pointer to an index.
* coffcode.h (coff_slurp_symbol_table <C_BSTAT>): Sanity check
symbol value before converting to a pointer.
-rw-r--r-- | bfd/coff-bfd.c | 9 | ||||
-rw-r--r-- | bfd/coffcode.h | 19 |
2 files changed, 18 insertions, 10 deletions
diff --git a/bfd/coff-bfd.c b/bfd/coff-bfd.c index 292778e..9aceeb0 100644 --- a/bfd/coff-bfd.c +++ b/bfd/coff-bfd.c @@ -45,9 +45,12 @@ bfd_coff_get_syment (bfd *abfd, *psyment = csym->native->u.syment; if (csym->native->fix_value) - psyment->n_value = - ((psyment->n_value - (uintptr_t) obj_raw_syments (abfd)) - / sizeof (combined_entry_type)); + { + psyment->n_value = + ((psyment->n_value - (uintptr_t) obj_raw_syments (abfd)) + / sizeof (combined_entry_type)); + csym->native->fix_value = 0; + } /* FIXME: We should handle fix_line here. */ diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 423f6c0..594f3e0 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -4852,13 +4852,18 @@ coff_slurp_symbol_table (bfd * abfd) case C_BSTAT: dst->symbol.flags = BSF_DEBUGGING; - /* The value is actually a symbol index. Save a pointer - to the symbol instead of the index. FIXME: This - should use a union. */ - src->u.syment.n_value - = (uintptr_t) (native_symbols + src->u.syment.n_value); - dst->symbol.value = src->u.syment.n_value; - src->fix_value = 1; + if (src->u.syment.n_value >= obj_raw_syment_count (abfd)) + dst->symbol.value = 0; + else + { + /* The value is actually a symbol index. Save a pointer + to the symbol instead of the index. FIXME: This + should use a union. */ + src->u.syment.n_value + = (uintptr_t) (native_symbols + src->u.syment.n_value); + dst->symbol.value = src->u.syment.n_value; + src->fix_value = 1; + } break; #endif |