diff options
author | kib <kib@FreeBSD.org> | 2011-01-08 17:11:49 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-01-08 17:11:49 +0000 |
commit | 5cec74bed917b7e7fe4e854d8ee69bbc3a117817 (patch) | |
tree | 0882ce7d12d36adab2adfd0186d9396cb4ab972f /libexec/rtld-elf/map_object.c | |
parent | 90de4ffc1a4a4d4d4f9f496f70a225b61a6acd34 (diff) | |
download | FreeBSD-src-5cec74bed917b7e7fe4e854d8ee69bbc3a117817.zip FreeBSD-src-5cec74bed917b7e7fe4e854d8ee69bbc3a117817.tar.gz |
In rtld, read the initial stack access mode from AT_STACKPROT as set
by kernel, and parse PT_GNU_STACK phdr from linked and loaded dsos.
If the loaded dso requires executable stack, as specified by PF_X bit
of p_flags of PT_GNU_STACK phdr, but current stack protection does not
permit execution, the __pthread_map_stacks_exec symbol is looked up
and called. It should be implemented in libc or threading library and
change the protection mode of all thread stacks to be executable.
Provide a private interface _rtld_get_stack_prot() to export the stack
access mode as calculated by rtld.
Reviewed by: kan
Diffstat (limited to 'libexec/rtld-elf/map_object.c')
-rw-r--r-- | libexec/rtld-elf/map_object.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index d231830..3f69e9b 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -83,6 +83,7 @@ map_object(int fd, const char *path, const struct stat *sb) Elf_Addr bss_vaddr; Elf_Addr bss_vlimit; caddr_t bss_addr; + Elf_Word stack_flags; hdr = get_elf_header(fd, path); if (hdr == NULL) @@ -100,6 +101,7 @@ map_object(int fd, const char *path, const struct stat *sb) phdyn = phinterp = phtls = NULL; phdr_vaddr = 0; segs = alloca(sizeof(segs[0]) * hdr->e_phnum); + stack_flags = PF_X | PF_R | PF_W; while (phdr < phlimit) { switch (phdr->p_type) { @@ -128,6 +130,10 @@ map_object(int fd, const char *path, const struct stat *sb) case PT_TLS: phtls = phdr; break; + + case PT_GNU_STACK: + stack_flags = phdr->p_flags; + break; } ++phdr; @@ -261,6 +267,7 @@ map_object(int fd, const char *path, const struct stat *sb) obj->tlsinitsize = phtls->p_filesz; obj->tlsinit = mapbase + phtls->p_vaddr; } + obj->stack_flags = stack_flags; return obj; } |