diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2022-12-04 15:42:08 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2022-12-04 15:42:08 +0000 |
commit | aad72e878b29386278de18dc4e4c47cbb8995caf (patch) | |
tree | 52d8e81f494e35cbf2532730d3331ba1353a4109 /libexec/ld.so/library_mquery.c | |
parent | 6db5eb96ea53ae5d57b7b24378ac6268fbdbdc9e (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.c | 21 |
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); } |