Date: Thu, 12 Aug 2021 13:49:53 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: f53932dfc411 - stable/13 - link_elf_obj: Invoke fini callbacks Message-ID: <202108121349.17CDnrFO052545@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=f53932dfc411fbab6f8d8fbca8727a97cc5b92a9 commit f53932dfc411fbab6f8d8fbca8727a97cc5b92a9 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-07-29 13:46:25 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-08-12 13:43:41 +0000 link_elf_obj: Invoke fini callbacks This is required for KASAN: when a module is unloaded, poisoned regions (e.g., pad areas between global variables) are left as such, so if they are reused as KLDs are loaded, false positives can arise. Reported by: pho, Jenkins Reviewed by: kib Sponsored by: The FreeBSD Foundation (cherry picked from commit 9e575fadf491152fb3445d4837d49a9cb87dd6e2) --- sys/kern/kern_linker.c | 2 ++ sys/kern/link_elf_obj.c | 32 +++++++++++++++++++++++++++++--- sys/sys/linker.h | 6 ++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index dbbf240a2f56..cb5d587bfbbc 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -613,6 +613,8 @@ linker_make_file(const char *pathname, linker_class_t lc) return (NULL); lf->ctors_addr = 0; lf->ctors_size = 0; + lf->dtors_addr = 0; + lf->dtors_size = 0; lf->refs = 1; lf->userrefs = 0; lf->flags = 0; diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 65b997b513e3..91852939e5e8 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -544,6 +544,17 @@ link_elf_link_preload(linker_class_t cls, const char *filename, lf->ctors_addr = ef->progtab[pb].addr; lf->ctors_size = shdr[i].sh_size; } + } else if ((ef->progtab[pb].name != NULL && + strcmp(ef->progtab[pb].name, ".dtors") == 0) || + shdr[i].sh_type == SHT_FINI_ARRAY) { + if (lf->dtors_addr != 0) { + printf( + "%s: multiple dtor sections in %s\n", + __func__, filename); + } else { + lf->dtors_addr = ef->progtab[pb].addr; + lf->dtors_size = shdr[i].sh_size; + } } /* Update all symbol values with the offset. */ @@ -612,7 +623,7 @@ out: } static void -link_elf_invoke_ctors(caddr_t addr, size_t size) +link_elf_invoke_cbs(caddr_t addr, size_t size) { void (**ctor)(void); size_t i, cnt; @@ -653,7 +664,7 @@ link_elf_link_preload_finish(linker_file_t lf) /* Apply protections now that relocation processing is complete. */ link_elf_protect(ef); - link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); + link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); return (0); } @@ -1012,6 +1023,19 @@ link_elf_load_file(linker_class_t cls, const char *filename, lf->ctors_size = shdr[i].sh_size; } + } else if (!strcmp(ef->progtab[pb].name, + ".dtors") || + shdr[i].sh_type == SHT_FINI_ARRAY) { + if (lf->dtors_addr != 0) { + printf( + "%s: multiple dtor sections in %s\n", + __func__, filename); + } else { + lf->dtors_addr = + (caddr_t)mapbase; + lf->dtors_size = + shdr[i].sh_size; + } } } else if (shdr[i].sh_type == SHT_PROGBITS) ef->progtab[pb].name = "<<PROGBITS>>"; @@ -1196,7 +1220,7 @@ link_elf_load_file(linker_class_t cls, const char *filename, #endif link_elf_protect(ef); - link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); + link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); *result = lf; out: @@ -1216,6 +1240,8 @@ link_elf_unload_file(linker_file_t file) elf_file_t ef = (elf_file_t) file; u_int i; + link_elf_invoke_cbs(file->dtors_addr, file->dtors_size); + /* Notify MD code that a module is being unloaded. */ elf_cpu_unload_file(file); diff --git a/sys/sys/linker.h b/sys/sys/linker.h index 6423a3989a02..35c8449382cf 100644 --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -82,8 +82,10 @@ struct linker_file { int id; /* unique id */ caddr_t address; /* load address */ size_t size; /* size of file */ - caddr_t ctors_addr; /* address of .ctors */ - size_t ctors_size; /* size of .ctors */ + caddr_t ctors_addr; /* address of .ctors/.init_array */ + size_t ctors_size; /* size of .ctors/.init_array */ + caddr_t dtors_addr; /* address of .dtors/.fini_array */ + size_t dtors_size; /* size of .dtors/.fini_array */ int ndeps; /* number of dependencies */ linker_file_t* deps; /* list of dependencies */ STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108121349.17CDnrFO052545>