dtors were broken by trying to reuse DF_1_NODELETE to hint that this
authorderaadt <deraadt@openbsd.org>
Mon, 7 Nov 2022 10:35:26 +0000 (10:35 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 7 Nov 2022 10:35:26 +0000 (10:35 +0000)
library would never unload, and could be immutable.  Pass a seperate
flag for our purposes
Noticed from regress tests by anton, ok kettenis

libexec/ld.so/dlfcn.c
libexec/ld.so/library.c
libexec/ld.so/library_mquery.c
libexec/ld.so/library_subr.c
libexec/ld.so/loader.c
libexec/ld.so/resolve.h

index adde277..0881a10 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dlfcn.c,v 1.111 2022/08/20 14:11:31 sthen Exp $ */
+/*     $OpenBSD: dlfcn.c,v 1.112 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -90,7 +90,7 @@ dlopen(const char *libname, int flags)
            | (flags & RTLD_GLOBAL ? DF_1_GLOBAL : 0)
            | (flags & RTLD_NOLOAD ? DF_1_NOOPEN : 0)
            ;
-       object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO, obj_flags);
+       object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO, obj_flags, 0);
        if (object == 0) {
                DL_DEB(("dlopen: failed to open %s\n", libname));
                failed = 1;
index f8f6b99..eb641d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: library.c,v 1.87 2022/08/20 14:11:31 sthen Exp $ */
+/*     $OpenBSD: library.c,v 1.88 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 2002 Dale Rahn
@@ -96,7 +96,7 @@ unload:
 }
 
 elf_object_t *
-_dl_tryload_shlib(const char *libname, int type, int flags)
+_dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
 {
        int     libfile, i;
        struct load_list *next_load, *load_list = NULL;
@@ -315,6 +315,7 @@ _dl_tryload_shlib(const char *libname, int type, int flags)
                object->dev = sb.st_dev;
                object->inode = sb.st_ino;
                object->obj_flags |= flags;
+               object->nodelete = nodelete;
                object->relro_addr = relro_addr;
                object->relro_size = relro_size;
                _dl_set_sod(object->load_name, &object->sod);
index 29893bd..6903263 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: library_mquery.c,v 1.67 2022/08/20 14:11:31 sthen Exp $ */
+/*     $OpenBSD: library_mquery.c,v 1.68 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 2002 Dale Rahn
@@ -101,7 +101,7 @@ unload:
 
 
 elf_object_t *
-_dl_tryload_shlib(const char *libname, int type, int flags)
+_dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
 {
        int libfile, i;
        struct load_list *ld, *lowld = NULL;
@@ -322,6 +322,7 @@ retry:
                object->dev = sb.st_dev;
                object->inode = sb.st_ino;
                object->obj_flags |= flags;
+               object->nodelete = nodelete;
                object->relro_addr = relro_addr;
                object->relro_size = relro_size;
                _dl_set_sod(object->load_name, &object->sod);
index f8c059e..c7826c3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: library_subr.c,v 1.52 2022/08/20 14:11:31 sthen Exp $ */
+/*     $OpenBSD: library_subr.c,v 1.53 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 2002 Dale Rahn
@@ -310,7 +310,8 @@ _dl_find_loaded_shlib(const char *req_name, struct sod req_sod, int flags)
  */
 
 elf_object_t *
-_dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags)
+_dl_load_shlib(const char *libname, elf_object_t *parent, int type, int flags,
+    int nodelete)
 {
        int try_any_minor, ignore_hints;
        struct sod sod, req_sod;
@@ -423,7 +424,7 @@ done:
                            "using it anyway\n",
                            sod.sod_name, sod.sod_major,
                            req_sod.sod_minor, sod.sod_minor);
-               object = _dl_tryload_shlib(hint, type, flags);
+               object = _dl_tryload_shlib(hint, type, flags, nodelete);
        }
        _dl_free((char *)sod.sod_name);
        return(object);
index 1a34127..c0cf506 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: loader.c,v 1.200 2022/11/06 12:00:20 deraadt Exp $ */
+/*     $OpenBSD: loader.c,v 1.201 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -247,7 +247,7 @@ _dl_dopreload(char *paths)
        dp = paths;
        while ((cp = _dl_strsep(&dp, ":")) != NULL) {
                shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB,
-                   _dl_objects->obj_flags);
+                   _dl_objects->obj_flags, 1);
                if (shlib == NULL)
                        _dl_die("can't preload library '%s'", cp);
                _dl_add_object(shlib);
@@ -326,10 +326,6 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
                /* propagate DF_1_NOW to deplibs (can be set by dynamic tags) */
                depflags = flags | (dynobj->obj_flags & DF_1_NOW);
 
-               /* Startup libraries are never unmapped and can be immutable */
-               if (booting)
-                       depflags |= DF_1_NODELETE;
-
                for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) {
                        if (dynp->d_tag == DT_NEEDED) {
                                libcount++;
@@ -379,7 +375,7 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
                                DL_DEB(("loading: %s required by %s\n", libname,
                                    dynobj->load_name));
                                depobj = _dl_load_shlib(libname, dynobj,
-                                   OBJTYPE_LIB, depflags);
+                                   OBJTYPE_LIB, depflags, booting);
                                if (depobj == 0) {
                                        if (booting) {
                                                _dl_die(
@@ -811,7 +807,7 @@ _dl_relro(elf_object_t *object)
                _dl_mprotect((void *)addr, object->relro_size, PROT_READ);
 
                /* if library will never be unloaded, RELRO can be immutable */
-               if ((object->obj_flags & DF_1_NODELETE))
+               if (object->nodelete)
                        _dl_mimmutable((void *)addr, object->relro_size);
        }
 }
index ede1701..941ab89 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolve.h,v 1.101 2022/08/20 14:11:31 sthen Exp $ */
+/*     $OpenBSD: resolve.h,v 1.102 2022/11/07 10:35:26 deraadt Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -77,6 +77,12 @@ struct object_vector {
 };
 void   object_vec_grow(struct object_vector *_vec, int _more);
 
+struct mutate {
+       vaddr_t start;
+       vaddr_t end;
+       int valid;
+};
+
 /*
  *  Structure describing a loaded object.
  *  The head of this struct must be compatible
@@ -163,6 +169,7 @@ struct elf_object {
 #define        OBJTYPE_LIB     3
 #define        OBJTYPE_DLO     4
        int             obj_flags;      /* c.f. <sys/exec_elf.h> DF_1_* */
+       int             nodelete;
 
        /* shared by ELF and GNU hash */
        u_int32_t       nbuckets;
@@ -256,8 +263,10 @@ void       _dl_remove_object(elf_object_t *object);
 void   _dl_cleanup_objects(void);
 
 void _dl_handle_already_loaded(elf_object_t *_object, int _flags);
-elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int);
-elf_object_t *_dl_tryload_shlib(const char *libname, int type, int flags);
+elf_object_t *_dl_load_shlib(const char *, elf_object_t *,
+    int, int, int nodelete);
+elf_object_t *_dl_tryload_shlib(const char *libname, int type,
+    int flags, int nodelete);
 
 int _dl_md_reloc(elf_object_t *object, int rel, int relsz);
 int _dl_md_reloc_got(elf_object_t *object, int lazy);