diff options
author | kib <kib@FreeBSD.org> | 2011-01-08 16:30:59 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-01-08 16:30:59 +0000 |
commit | 90de4ffc1a4a4d4d4f9f496f70a225b61a6acd34 (patch) | |
tree | 9548af4ee1ffe3cd4fa5fa801fa2a1d2c128b2c3 /sys/kern/imgact_elf.c | |
parent | 06eb8de1e11605ee7d4ae2e5c58cdadccc659f0d (diff) | |
download | FreeBSD-src-90de4ffc1a4a4d4d4f9f496f70a225b61a6acd34.zip FreeBSD-src-90de4ffc1a4a4d4d4f9f496f70a225b61a6acd34.tar.gz |
In elf image activator, read and apply the stack protection mode from
PT_GNU_STACK program header, if present and enabled. Two new sysctls
are provided, kern.elf32.nxstack and kern.elf64.nxstack, that allow to
enable PT_GNU_STACK for ABIs of specified bitsize, if ABI decided to
support shared page.
Inform rtld about access mode of the stack initial mapping by
AT_STACKPROT aux vector.
At the moment, the default is disabled, waiting for the usermode
support bits.
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r-- | sys/kern/imgact_elf.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index d34da70..57001b0 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -115,6 +115,11 @@ static int elf_legacy_coredump = 0; SYSCTL_INT(_debug, OID_AUTO, __elfN(legacy_coredump), CTLFLAG_RW, &elf_legacy_coredump, 0, ""); +static int __elfN(nxstack) = 0; +SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, + nxstack, CTLFLAG_RW, &__elfN(nxstack), 0, + __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": enable non-executable stack"); + static Elf_Brandinfo *elf_brand_list[MAX_BRANDS]; #define trunc_page_ps(va, ps) ((va) & ~(ps - 1)) @@ -724,19 +729,24 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) n = 0; baddr = 0; for (i = 0; i < hdr->e_phnum; i++) { - if (phdr[i].p_type == PT_LOAD) { + switch (phdr[i].p_type) { + case PT_LOAD: if (n == 0) baddr = phdr[i].p_vaddr; n++; - continue; - } - if (phdr[i].p_type == PT_INTERP) { + break; + case PT_INTERP: /* Path to interpreter */ if (phdr[i].p_filesz > MAXPATHLEN || phdr[i].p_offset + phdr[i].p_filesz > PAGE_SIZE) return (ENOEXEC); interp = imgp->image_header + phdr[i].p_offset; - continue; + break; + case PT_GNU_STACK: + if (__elfN(nxstack)) + imgp->stack_prot = + __elfN(trans_prot)(phdr[i].p_flags); + break; } } @@ -972,6 +982,8 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_PAGESIZES, imgp->pagesizes); AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen); } + AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->stack_prot != 0 ? + imgp->stack_prot : imgp->sysent->sv_stackprot); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); |