The branch stable/13 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f53932dfc411fbab6f8d8fbca8727a97cc5b92a9

commit f53932dfc411fbab6f8d8fbca8727a97cc5b92a9
Author:     Mark Johnston <[email protected]>
AuthorDate: 2021-07-29 13:46:25 +0000
Commit:     Mark Johnston <[email protected]>
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 */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to