From 69003e0590e1fc50391a639b285200403a58ad01 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 21 Jan 2014 00:36:35 -0500 Subject: fix crash in dynamic linker when certain copy relocations are unsatisfied STB_WEAK is only a weak reference for undefined symbols (those with a section of SHN_UNDEF). otherwise, it's a weak definition. normally this distinction would not matter, since a relocation referencing a symbol that also provides a definition (not SHN_UNDEF) will always succeed in finding the referenced symbol itself. however, in the case of copy relocations, the referenced symbol itself is ignored in order to search for another symbol to copy from, and thus it's possible that no definition is found. in this case, if the symbol being resolved happened to be a weak definition, it was misinterpreted as a weak reference, suppressing the error path and causing a crash when the copy relocation was performed with a null source pointer passed to memcpy. there are almost certainly still situations in which invalid combinations of symbol and relocation types can cause the dynamic linker to crash (this is pretty much inevitable), but the intent is that crashes not be possible for symbol/relocation tables produced by a valid linker. --- src/ldso/dynlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ldso') diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 89e1260b..a1bdf0fb 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -253,7 +253,8 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri name = strings + sym->st_name; ctx = IS_COPY(type) ? head->next : head; def = find_sym(ctx, name, IS_PLT(type)); - if (!def.sym && sym->st_info>>4 != STB_WEAK) { + if (!def.sym && (sym->st_shndx != SHN_UNDEF + || sym->st_info>>4 != STB_WEAK)) { snprintf(errbuf, sizeof errbuf, "Error relocating %s: %s: symbol not found", dso->name, name); -- cgit v1.2.1