summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2022-11-07 10:35:27 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2022-11-07 10:35:27 +0000
commitae8fa8e38df115a1ea86b802d6bddc7aff1e3b94 (patch)
tree22240b339e0caaa9a772b5cc34d2bcf0548ba0bc
parentc3c809451e9b0e5d7c0681491ff510b3ae0cbaec (diff)
dtors were broken by trying to reuse DF_1_NODELETE to hint that this
library would never unload, and could be immutable. Pass a seperate flag for our purposes Noticed from regress tests by anton, ok kettenis
-rw-r--r--libexec/ld.so/dlfcn.c4
-rw-r--r--libexec/ld.so/library.c5
-rw-r--r--libexec/ld.so/library_mquery.c5
-rw-r--r--libexec/ld.so/library_subr.c7
-rw-r--r--libexec/ld.so/loader.c12
-rw-r--r--libexec/ld.so/resolve.h15
6 files changed, 28 insertions, 20 deletions
diff --git a/libexec/ld.so/dlfcn.c b/libexec/ld.so/dlfcn.c
index adde27790a8..0881a10f45b 100644
--- a/libexec/ld.so/dlfcn.c
+++ b/libexec/ld.so/dlfcn.c
@@ -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;
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index f8f6b991477..eb641d99c53 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -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);
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c
index 29893bdc6b2..6903263b7f9 100644
--- a/libexec/ld.so/library_mquery.c
+++ b/libexec/ld.so/library_mquery.c
@@ -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);
diff --git a/libexec/ld.so/library_subr.c b/libexec/ld.so/library_subr.c
index f8c059ee249..c7826c336fe 100644
--- a/libexec/ld.so/library_subr.c
+++ b/libexec/ld.so/library_subr.c
@@ -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);
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 1a34127ab81..c0cf506cbd7 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -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);
}
}
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index ede1701326f..941ab891110 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -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);