summaryrefslogtreecommitdiff
path: root/libexec/ld.so/library_mquery.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2022-12-04 15:42:08 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2022-12-04 15:42:08 +0000
commitaad72e878b29386278de18dc4e4c47cbb8995caf (patch)
tree52d8e81f494e35cbf2532730d3331ba1353a4109 /libexec/ld.so/library_mquery.c
parent6db5eb96ea53ae5d57b7b24378ac6268fbdbdc9e (diff)
The next step for mimmutable(). ld.so figures out what regions of memory
of startup shared library mappings can be made immutable, and also does this for dlope() RTLD_NODELETE and subsidiary libraries. Complexity in this diff is due to the GNU_RELRO and OPENBSD_MUTABLE sections. Tested in snaps for about 3 weeks, with some bootstrap related pain felt in ports ok kettenis, much help from others.
Diffstat (limited to 'libexec/ld.so/library_mquery.c')
-rw-r--r--libexec/ld.so/library_mquery.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c
index 6903263b7f9..143c44c526b 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.68 2022/11/07 10:35:26 deraadt Exp $ */
+/* $OpenBSD: library_mquery.c,v 1.69 2022/12/04 15:42:07 deraadt Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -103,6 +103,7 @@ unload:
elf_object_t *
_dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
{
+ struct mutate imut[MAXMUT], mut[MAXMUT];
int libfile, i;
struct load_list *ld, *lowld = NULL;
elf_object_t *object;
@@ -231,6 +232,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
#define LOFF ((Elf_Addr)lowld->start - lowld->moff)
retry:
+ _dl_memset(&mut, 0, sizeof mut);
+ _dl_memset(&imut, 0, sizeof imut);
exec_start = NULL;
exec_size = 0;
for (ld = lowld; ld != NULL; ld = ld->next) {
@@ -285,6 +288,9 @@ retry:
exec_size = ROUND_PG(ld->size);
}
+ /* Entire mapping can become immutable, minus exceptions chosen later */
+ _dl_defer_immut(imut, LOFF + ld->moff, ROUND_PG(ld->size));
+
ld->start = res;
}
@@ -298,12 +304,19 @@ retry:
phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++, phdp++) {
- if (phdp->p_type == PT_OPENBSD_RANDOMIZE)
+ switch (phdp->p_type) {
+ case PT_OPENBSD_RANDOMIZE:
_dl_arc4randombuf((char *)(phdp->p_vaddr + LOFF),
phdp->p_memsz);
- else if (phdp->p_type == PT_GNU_RELRO) {
+ break;
+ case PT_GNU_RELRO:
relro_addr = phdp->p_vaddr + LOFF;
relro_size = phdp->p_memsz;
+ _dl_defer_mut(mut, phdp->p_vaddr + LOFF, phdp->p_memsz);
+ break;
+ case PT_OPENBSD_MUTABLE:
+ _dl_defer_mut(mut, phdp->p_vaddr + LOFF, phdp->p_memsz);
+ break;
}
}
@@ -337,6 +350,8 @@ retry:
_dl_printf("msyscall %lx %lx error\n",
exec_start, exec_size);
}
+ _dl_bcopy(mut, object->mut, sizeof mut);
+ _dl_bcopy(imut, object->imut, sizeof imut);
} else {
_dl_load_list_free(lowld);
}