From 2043ddb2185096eadc111865f31a70d1cffd6f4c Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 24 Apr 2023 11:19:15 +0930 Subject: [PATCH] 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 ): Sanity check symbol value before converting to a pointer. --- bfd/coff-bfd.c | 9 ++++++--- bfd/coffcode.h | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/bfd/coff-bfd.c b/bfd/coff-bfd.c index 292778ecb56..9aceeb080a7 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 423f6c070ef..594f3e0457b 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 -- 2.30.2