diff --git a/contrib/gcc/config/i386/freebsd.h b/contrib/gcc/config/i386/freebsd.h index 53de63f..a69a8c6 100644 --- a/contrib/gcc/config/i386/freebsd.h +++ b/contrib/gcc/config/i386/freebsd.h @@ -239,3 +239,6 @@ Boston, MA 02110-1301, USA. */ XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \ fprintf (asm_out_file, "\n"); \ } while (0) + +#undef NEED_INDICATE_EXEC_STACK +#define NEED_INDICATE_EXEC_STACK 1 diff --git a/lib/csu/amd64/crti.S b/lib/csu/amd64/crti.S index 37698ba..618dca1 100644 --- a/lib/csu/amd64/crti.S +++ b/lib/csu/amd64/crti.S @@ -39,3 +39,5 @@ _init: .type _fini,@function _fini: subq $8,%rsp + + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/amd64/crtn.S b/lib/csu/amd64/crtn.S index eb6d4df..c411f00 100644 --- a/lib/csu/amd64/crtn.S +++ b/lib/csu/amd64/crtn.S @@ -33,3 +33,5 @@ __FBSDID("$FreeBSD$"); .section .fini,"ax",@progbits addq $8,%rsp ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/i386-elf/crt1_s.S b/lib/csu/i386-elf/crt1_s.S index f8c1d73..d7ed0a2 100644 --- a/lib/csu/i386-elf/crt1_s.S +++ b/lib/csu/i386-elf/crt1_s.S @@ -49,3 +49,5 @@ _start: int3 .cfi_endproc .size _start, . - _start + + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/i386-elf/crti.S b/lib/csu/i386-elf/crti.S index 608dc21..77e4e77 100644 --- a/lib/csu/i386-elf/crti.S +++ b/lib/csu/i386-elf/crti.S @@ -39,3 +39,5 @@ _init: .type _fini,@function _fini: sub $12,%esp /* re-align stack pointer */ + + .section .note.GNU-stack,"",%progbits diff --git a/lib/csu/i386-elf/crtn.S b/lib/csu/i386-elf/crtn.S index 9ce5bec..0264e22 100644 --- a/lib/csu/i386-elf/crtn.S +++ b/lib/csu/i386-elf/crtn.S @@ -33,3 +33,5 @@ __FBSDID("$FreeBSD$"); .section .fini,"ax",@progbits add $12,%esp ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S index 38c3c6f..9035632 100644 --- a/lib/libc/amd64/gen/_setjmp.S +++ b/lib/libc/amd64/gen/_setjmp.S @@ -92,3 +92,5 @@ ENTRY(___longjmp) 1: movq %rcx,0(%rsp) ret END(___longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/fabs.S b/lib/libc/amd64/gen/fabs.S index 8c0c8bf..2ace0f9 100644 --- a/lib/libc/amd64/gen/fabs.S +++ b/lib/libc/amd64/gen/fabs.S @@ -42,3 +42,5 @@ END(fabs) .data signbit: .quad 0x8000000000000000 + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/modf.S b/lib/libc/amd64/gen/modf.S index 4fee38b..691aad8 100644 --- a/lib/libc/amd64/gen/modf.S +++ b/lib/libc/amd64/gen/modf.S @@ -87,3 +87,5 @@ ENTRY(modf) ret END(modf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/rfork_thread.S b/lib/libc/amd64/gen/rfork_thread.S index c34a940..9720e08 100644 --- a/lib/libc/amd64/gen/rfork_thread.S +++ b/lib/libc/amd64/gen/rfork_thread.S @@ -100,3 +100,5 @@ ENTRY(rfork_thread) jmp HIDENAME(cerror) #endif END(rfork_thread) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S index 41de587..1409f4c 100644 --- a/lib/libc/amd64/gen/setjmp.S +++ b/lib/libc/amd64/gen/setjmp.S @@ -110,3 +110,5 @@ ENTRY(__longjmp) 1: movq %rcx,0(%rsp) ret END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S index 8da4867..438d440 100644 --- a/lib/libc/amd64/gen/sigsetjmp.S +++ b/lib/libc/amd64/gen/sigsetjmp.S @@ -111,3 +111,5 @@ ENTRY(__siglongjmp) 1: movq %rcx,0(%rsp) ret END(__siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/div.S b/lib/libc/amd64/stdlib/div.S index f3c2a59..366010c 100644 --- a/lib/libc/amd64/stdlib/div.S +++ b/lib/libc/amd64/stdlib/div.S @@ -16,3 +16,5 @@ ENTRY(div) orq %rdx,%rax ret END(div) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/ldiv.S b/lib/libc/amd64/stdlib/ldiv.S index 2a0a8cf..f11472c 100644 --- a/lib/libc/amd64/stdlib/ldiv.S +++ b/lib/libc/amd64/stdlib/ldiv.S @@ -14,3 +14,5 @@ ENTRY(ldiv) idivq %rsi ret END(ldiv) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/lldiv.S b/lib/libc/amd64/stdlib/lldiv.S index e5ae5ca..4dab0fd 100644 --- a/lib/libc/amd64/stdlib/lldiv.S +++ b/lib/libc/amd64/stdlib/lldiv.S @@ -14,3 +14,5 @@ ENTRY(lldiv) idivq %rsi ret END(lldiv) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bcmp.S b/lib/libc/amd64/string/bcmp.S index 375c3bc..d01b76b 100644 --- a/lib/libc/amd64/string/bcmp.S +++ b/lib/libc/amd64/string/bcmp.S @@ -23,3 +23,5 @@ L1: movsbl %al,%eax ret END(bcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bcopy.S b/lib/libc/amd64/string/bcopy.S index f7aa6d1..cc38f47 100644 --- a/lib/libc/amd64/string/bcopy.S +++ b/lib/libc/amd64/string/bcopy.S @@ -95,3 +95,5 @@ END(memmove) END(bcopy) #endif #endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bzero.S b/lib/libc/amd64/string/bzero.S index 0de67d3..cf46a2a 100644 --- a/lib/libc/amd64/string/bzero.S +++ b/lib/libc/amd64/string/bzero.S @@ -42,3 +42,5 @@ L1: movq %rsi,%rcx /* zero remainder by bytes */ ret END(bzero) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memcmp.S b/lib/libc/amd64/string/memcmp.S index a039b5b..66d64a0 100644 --- a/lib/libc/amd64/string/memcmp.S +++ b/lib/libc/amd64/string/memcmp.S @@ -40,3 +40,5 @@ L6: xorl %eax,%eax /* Perform unsigned comparison */ subl %edx,%eax ret END(memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memmove.S b/lib/libc/amd64/string/memmove.S index 85beb26..a303c60 100644 --- a/lib/libc/amd64/string/memmove.S +++ b/lib/libc/amd64/string/memmove.S @@ -3,3 +3,5 @@ #define MEMMOVE #include "bcopy.S" + + .section .note.GNU-stack,"",%progbist diff --git a/lib/libc/amd64/string/memset.S b/lib/libc/amd64/string/memset.S index ed8ba24..84d1562 100644 --- a/lib/libc/amd64/string/memset.S +++ b/lib/libc/amd64/string/memset.S @@ -59,3 +59,5 @@ L1: rep ret END(memset) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcat.S b/lib/libc/amd64/string/strcat.S index b241ffc..7b5a1dd 100644 --- a/lib/libc/amd64/string/strcat.S +++ b/lib/libc/amd64/string/strcat.S @@ -164,3 +164,5 @@ ENTRY(strcat) .Ldone: ret END(strcat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcmp.S b/lib/libc/amd64/string/strcmp.S index 81f54cb..07009c1 100644 --- a/lib/libc/amd64/string/strcmp.S +++ b/lib/libc/amd64/string/strcmp.S @@ -72,3 +72,5 @@ ENTRY(strcmp) subq %rdx,%rax ret END(strcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcpy.S b/lib/libc/amd64/string/strcpy.S index 8cafa12..5feb925 100644 --- a/lib/libc/amd64/string/strcpy.S +++ b/lib/libc/amd64/string/strcpy.S @@ -110,3 +110,5 @@ ENTRY(strcpy) .Ldone: ret END(strcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/brk.S b/lib/libc/amd64/sys/brk.S index c25daff..2319417 100644 --- a/lib/libc/amd64/sys/brk.S +++ b/lib/libc/amd64/sys/brk.S @@ -83,3 +83,5 @@ err: jmp HIDENAME(cerror) #endif END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/cerror.S b/lib/libc/amd64/sys/cerror.S index 547a18c..d01cf4a 100644 --- a/lib/libc/amd64/sys/cerror.S +++ b/lib/libc/amd64/sys/cerror.S @@ -56,3 +56,4 @@ HIDENAME(cerror): movq $-1,%rdx ret + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/exect.S b/lib/libc/amd64/sys/exect.S index 93125fa..81dc8e5 100644 --- a/lib/libc/amd64/sys/exect.S +++ b/lib/libc/amd64/sys/exect.S @@ -54,3 +54,5 @@ ENTRY(exect) jmp HIDENAME(cerror) #endif END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/getcontext.S b/lib/libc/amd64/sys/getcontext.S index 08a6493..ea29adb 100644 --- a/lib/libc/amd64/sys/getcontext.S +++ b/lib/libc/amd64/sys/getcontext.S @@ -53,3 +53,5 @@ ENTRY(__sys_getcontext) jmp HIDENAME(cerror) #endif END(__sys_getcontext) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/pipe.S b/lib/libc/amd64/sys/pipe.S index a286064..59c1ac1c 100644 --- a/lib/libc/amd64/sys/pipe.S +++ b/lib/libc/amd64/sys/pipe.S @@ -58,3 +58,5 @@ ENTRY(__sys_pipe) jmp HIDENAME(cerror) #endif END(__sys_pipe) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/ptrace.S b/lib/libc/amd64/sys/ptrace.S index 29ebade..6235390 100644 --- a/lib/libc/amd64/sys/ptrace.S +++ b/lib/libc/amd64/sys/ptrace.S @@ -58,3 +58,5 @@ err: jmp HIDENAME(cerror) #endif END(ptrace) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/reboot.S b/lib/libc/amd64/sys/reboot.S index 59df944..e79ca79 100644 --- a/lib/libc/amd64/sys/reboot.S +++ b/lib/libc/amd64/sys/reboot.S @@ -55,3 +55,5 @@ ENTRY(__sys_reboot) jmp HIDENAME(cerror) #endif END(__sys_reboot) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/sbrk.S b/lib/libc/amd64/sys/sbrk.S index fed3882..3e4d8aa 100644 --- a/lib/libc/amd64/sys/sbrk.S +++ b/lib/libc/amd64/sys/sbrk.S @@ -86,3 +86,5 @@ err: jmp HIDENAME(cerror) #endif END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/setlogin.S b/lib/libc/amd64/sys/setlogin.S index 649289a..23692b9 100644 --- a/lib/libc/amd64/sys/setlogin.S +++ b/lib/libc/amd64/sys/setlogin.S @@ -63,3 +63,5 @@ ENTRY(__sys_setlogin) jmp HIDENAME(cerror) #endif END(__sys_setlogin) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/sigreturn.S b/lib/libc/amd64/sys/sigreturn.S index 28dc227..f91816e 100644 --- a/lib/libc/amd64/sys/sigreturn.S +++ b/lib/libc/amd64/sys/sigreturn.S @@ -44,3 +44,5 @@ __FBSDID("$FreeBSD$"); */ RSYSCALL(sigreturn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S index d955e5f..555c3ca 100644 --- a/lib/libc/amd64/sys/vfork.S +++ b/lib/libc/amd64/sys/vfork.S @@ -57,3 +57,5 @@ ENTRY(__sys_vfork) jmp HIDENAME(cerror) #endif END(__sys_vfork) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index f9abab5..32cf92c 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -453,6 +453,7 @@ FBSDprivate_1.0 { _rtld_atfork_pre; _rtld_atfork_post; _rtld_error; /* for private use */ + _rtld_get_stack_prot; _rtld_thread_init; /* for private use */ __elf_phdr_match_addr; _err; @@ -499,4 +500,5 @@ FBSDprivate_1.0 { _libc_sem_getvalue_compat; __elf_aux_vector; + __pthread_map_stacks_exec; }; diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c index 930ebc1..b109cc9 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); /* * Linkage to services provided by the dynamic linker. */ +#include #include #include #include @@ -165,3 +166,12 @@ _rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info) return (0); } + +#pragma weak _rtld_get_stack_prot +int +_rtld_get_stack_prot(void) +{ + + return (PROT_EXEC | PROT_READ | PROT_WRITE); +} + diff --git a/lib/libc/gen/elf_utils.c b/lib/libc/gen/elf_utils.c index 9ee5f41..7bd7511 100644 --- a/lib/libc/gen/elf_utils.c +++ b/lib/libc/gen/elf_utils.c @@ -26,7 +26,12 @@ * $FreeBSD$ */ +#include +#include +#include +#include #include +#include int __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) @@ -45,3 +50,25 @@ __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) } return (i != phdr_info->dlpi_phnum); } + +#pragma weak __pthread_map_stacks_exec +void +__pthread_map_stacks_exec(void) +{ + int mib[2]; + struct rlimit rlim; + u_long usrstack; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_USRSTACK; + len = sizeof(usrstack); + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0) + == -1) + return; + if (getrlimit(RLIMIT_STACK, &rlim) == -1) + return; + mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), + rlim.rlim_cur, _rtld_get_stack_prot()); +} + diff --git a/lib/libc/i386/gen/_ctx_start.S b/lib/libc/i386/gen/_ctx_start.S index 7083d3c..fdea371 100644 --- a/lib/libc/i386/gen/_ctx_start.S +++ b/lib/libc/i386/gen/_ctx_start.S @@ -50,3 +50,5 @@ ENTRY(_ctx_start) call PIC_PLT(abort) /* fubar */ ret END(_ctx_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/_setjmp.S b/lib/libc/i386/gen/_setjmp.S index 7eb1ae3..3d9fdb4 100644 --- a/lib/libc/i386/gen/_setjmp.S +++ b/lib/libc/i386/gen/_setjmp.S @@ -78,3 +78,5 @@ ENTRY(___longjmp) 1: movl %ecx,0(%esp) ret END(___longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/fabs.S b/lib/libc/i386/gen/fabs.S index 9903fd3..7fb1531 100644 --- a/lib/libc/i386/gen/fabs.S +++ b/lib/libc/i386/gen/fabs.S @@ -41,3 +41,5 @@ ENTRY(fabs) fabs ret END(fabs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/modf.S b/lib/libc/i386/gen/modf.S index 0f7112e..33c211f 100644 --- a/lib/libc/i386/gen/modf.S +++ b/lib/libc/i386/gen/modf.S @@ -83,3 +83,5 @@ ENTRY(modf) leave ret END(modf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/rfork_thread.S b/lib/libc/i386/gen/rfork_thread.S index 841717a..3333d84 100644 --- a/lib/libc/i386/gen/rfork_thread.S +++ b/lib/libc/i386/gen/rfork_thread.S @@ -116,3 +116,5 @@ ENTRY(rfork_thread) PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) END(rfork_thread) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/setjmp.S b/lib/libc/i386/gen/setjmp.S index 6f6cd89..5d0ddc4 100644 --- a/lib/libc/i386/gen/setjmp.S +++ b/lib/libc/i386/gen/setjmp.S @@ -98,3 +98,5 @@ ENTRY(__longjmp) 1: movl %ecx,0(%esp) ret END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/gen/sigsetjmp.S b/lib/libc/i386/gen/sigsetjmp.S index 6134d03..6487745 100644 --- a/lib/libc/i386/gen/sigsetjmp.S +++ b/lib/libc/i386/gen/sigsetjmp.S @@ -110,3 +110,5 @@ ENTRY(__siglongjmp) 1: movl %ecx,0(%esp) ret END(__siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/stdlib/div.S b/lib/libc/i386/stdlib/div.S index 42e7ef4..81d6e6e 100644 --- a/lib/libc/i386/stdlib/div.S +++ b/lib/libc/i386/stdlib/div.S @@ -35,3 +35,5 @@ ENTRY(div) idiv %ecx ret END(div) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/stdlib/ldiv.S b/lib/libc/i386/stdlib/ldiv.S index b0455bf..c40c631 100644 --- a/lib/libc/i386/stdlib/ldiv.S +++ b/lib/libc/i386/stdlib/ldiv.S @@ -38,3 +38,5 @@ ENTRY(ldiv) idiv %ecx ret END(ldiv) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/bcmp.S b/lib/libc/i386/string/bcmp.S index eaf9666..b25ee6e 100644 --- a/lib/libc/i386/string/bcmp.S +++ b/lib/libc/i386/string/bcmp.S @@ -62,3 +62,5 @@ L1: popl %edi ret END(bcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/bcopy.S b/lib/libc/i386/string/bcopy.S index 2f3525e..cab1de6 100644 --- a/lib/libc/i386/string/bcopy.S +++ b/lib/libc/i386/string/bcopy.S @@ -106,3 +106,5 @@ END(memmove) END(bcopy) #endif #endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/bzero.S b/lib/libc/i386/string/bzero.S index 3c22b36..c8d3776 100644 --- a/lib/libc/i386/string/bzero.S +++ b/lib/libc/i386/string/bzero.S @@ -80,3 +80,5 @@ L1: rep popl %edi ret END(bzero) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/ffs.S b/lib/libc/i386/string/ffs.S index e668447..3a0431c 100644 --- a/lib/libc/i386/string/ffs.S +++ b/lib/libc/i386/string/ffs.S @@ -52,3 +52,5 @@ ENTRY(ffs) L1: xorl %eax,%eax /* clear result */ ret END(ffs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/index.S b/lib/libc/i386/string/index.S index e7e7a8c..3bdd68d 100644 --- a/lib/libc/i386/string/index.S +++ b/lib/libc/i386/string/index.S @@ -62,3 +62,5 @@ L2: popl %ebx ret END(index) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/memchr.S b/lib/libc/i386/string/memchr.S index a313d4d..03828db 100644 --- a/lib/libc/i386/string/memchr.S +++ b/lib/libc/i386/string/memchr.S @@ -57,3 +57,5 @@ L1: xorl %eax,%eax popl %edi ret END(memchr) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/memcmp.S b/lib/libc/i386/string/memcmp.S index fa9586f..cbb3b8a 100644 --- a/lib/libc/i386/string/memcmp.S +++ b/lib/libc/i386/string/memcmp.S @@ -74,3 +74,5 @@ L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */ popl %edi ret END(memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/memcpy.S b/lib/libc/i386/string/memcpy.S index f85a1a5..db5a3f4 100644 --- a/lib/libc/i386/string/memcpy.S +++ b/lib/libc/i386/string/memcpy.S @@ -3,3 +3,5 @@ __FBSDID("$FreeBSD$"); #define MEMCOPY #include "bcopy.S" + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/memmove.S b/lib/libc/i386/string/memmove.S index 02330c4..9179a50 100644 --- a/lib/libc/i386/string/memmove.S +++ b/lib/libc/i386/string/memmove.S @@ -3,3 +3,5 @@ __FBSDID("$FreeBSD$"); #define MEMMOVE #include "bcopy.S" + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/memset.S b/lib/libc/i386/string/memset.S index 25768c2..f5da603 100644 --- a/lib/libc/i386/string/memset.S +++ b/lib/libc/i386/string/memset.S @@ -88,3 +88,5 @@ L1: rep popl %edi ret END(memset) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/rindex.S b/lib/libc/i386/string/rindex.S index c52f6d3..e59406c 100644 --- a/lib/libc/i386/string/rindex.S +++ b/lib/libc/i386/string/rindex.S @@ -63,3 +63,5 @@ L2: popl %ebx ret END(rindex) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strcat.S b/lib/libc/i386/string/strcat.S index 6715bd8..835a7e9 100644 --- a/lib/libc/i386/string/strcat.S +++ b/lib/libc/i386/string/strcat.S @@ -99,3 +99,5 @@ L2: popl %eax /* pop destination address */ popl %edi /* restore edi */ ret END(strcat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strchr.S b/lib/libc/i386/string/strchr.S index 8c518fb..ddae795 100644 --- a/lib/libc/i386/string/strchr.S +++ b/lib/libc/i386/string/strchr.S @@ -62,3 +62,5 @@ L2: popl %ebx ret END(strchr) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strcmp.S b/lib/libc/i386/string/strcmp.S index 9ca104e..6599577 100644 --- a/lib/libc/i386/string/strcmp.S +++ b/lib/libc/i386/string/strcmp.S @@ -118,3 +118,5 @@ L3: movzbl (%eax),%eax /* unsigned comparison */ subl %edx,%eax ret END(strcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strcpy.S b/lib/libc/i386/string/strcpy.S index 7367c07..c5113f6 100644 --- a/lib/libc/i386/string/strcpy.S +++ b/lib/libc/i386/string/strcpy.S @@ -88,3 +88,5 @@ L1: movb (%edx),%al /* unroll loop, but not too much */ L2: popl %eax /* pop dst address */ ret END(strcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strncmp.S b/lib/libc/i386/string/strncmp.S index 98e3656..ec9b531 100644 --- a/lib/libc/i386/string/strncmp.S +++ b/lib/libc/i386/string/strncmp.S @@ -165,3 +165,5 @@ L4: xorl %eax,%eax popl %ebx ret END(strncmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/strrchr.S b/lib/libc/i386/string/strrchr.S index f044c2e..0d7f0ca 100644 --- a/lib/libc/i386/string/strrchr.S +++ b/lib/libc/i386/string/strrchr.S @@ -63,3 +63,5 @@ L2: popl %ebx ret END(strrchr) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/swab.S b/lib/libc/i386/string/swab.S index 5035de2..3d21e64 100644 --- a/lib/libc/i386/string/swab.S +++ b/lib/libc/i386/string/swab.S @@ -98,3 +98,5 @@ L4: popl %edi popl %esi ret END(swab) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/wcschr.S b/lib/libc/i386/string/wcschr.S index 8f6c543..37862a9 100644 --- a/lib/libc/i386/string/wcschr.S +++ b/lib/libc/i386/string/wcschr.S @@ -75,3 +75,5 @@ no: popl %ebx xorl %eax,%eax ret END(wcschr) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/wcscmp.S b/lib/libc/i386/string/wcscmp.S index 8d0700a..6fbcb8c 100644 --- a/lib/libc/i386/string/wcscmp.S +++ b/lib/libc/i386/string/wcscmp.S @@ -78,3 +78,5 @@ no0: subl (%esi),%eax popl %edi ret END(wcscmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/wcslen.S b/lib/libc/i386/string/wcslen.S index 9fea2b0..691e17f 100644 --- a/lib/libc/i386/string/wcslen.S +++ b/lib/libc/i386/string/wcslen.S @@ -67,3 +67,5 @@ found1: incl %eax found0: popl %ebx ret END(wcslen) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/string/wmemchr.S b/lib/libc/i386/string/wmemchr.S index 2b5270b..2e81c09 100644 --- a/lib/libc/i386/string/wmemchr.S +++ b/lib/libc/i386/string/wmemchr.S @@ -104,3 +104,5 @@ no: xorl %eax,%eax popl %edi ret END(wmemchr) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/Ovfork.S b/lib/libc/i386/sys/Ovfork.S index 25a9d94..e3cc45d 100644 --- a/lib/libc/i386/sys/Ovfork.S +++ b/lib/libc/i386/sys/Ovfork.S @@ -53,3 +53,5 @@ ENTRY(__sys_vfork) PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) END(__sys_vfork) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/brk.S b/lib/libc/i386/sys/brk.S index f67a2a2..968e437 100644 --- a/lib/libc/i386/sys/brk.S +++ b/lib/libc/i386/sys/brk.S @@ -86,3 +86,5 @@ err: jmp HIDENAME(cerror) #endif END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/cerror.S b/lib/libc/i386/sys/cerror.S index 3e8d539..129cc1b 100644 --- a/lib/libc/i386/sys/cerror.S +++ b/lib/libc/i386/sys/cerror.S @@ -63,3 +63,4 @@ HIDENAME(cerror): movl $-1,%edx ret + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/exect.S b/lib/libc/i386/sys/exect.S index 5eb0d44..3ae87b8 100644 --- a/lib/libc/i386/sys/exect.S +++ b/lib/libc/i386/sys/exect.S @@ -50,3 +50,5 @@ ENTRY(exect) PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) /* exect(file, argv, env); */ END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/getcontext.S b/lib/libc/i386/sys/getcontext.S index 6942749..c24dbdc 100644 --- a/lib/libc/i386/sys/getcontext.S +++ b/lib/libc/i386/sys/getcontext.S @@ -49,3 +49,5 @@ ENTRY(__sys_getcontext) PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) END(__sys_getcontext) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/pipe.S b/lib/libc/i386/sys/pipe.S index 0ce3a8c..85f4fd2 100644 --- a/lib/libc/i386/sys/pipe.S +++ b/lib/libc/i386/sys/pipe.S @@ -45,3 +45,5 @@ SYSCALL(pipe) movl $0,%eax ret END(__sys_pipe) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/ptrace.S b/lib/libc/i386/sys/ptrace.S index 7527e7e..6e5e885 100644 --- a/lib/libc/i386/sys/ptrace.S +++ b/lib/libc/i386/sys/ptrace.S @@ -56,3 +56,5 @@ err: PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) END(ptrace) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/reboot.S b/lib/libc/i386/sys/reboot.S index d5caccf..f11000e 100644 --- a/lib/libc/i386/sys/reboot.S +++ b/lib/libc/i386/sys/reboot.S @@ -41,3 +41,5 @@ __FBSDID("$FreeBSD$"); SYSCALL(reboot) iret END(__sys_reboot) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/sbrk.S b/lib/libc/i386/sys/sbrk.S index 36a1b55..337087a 100644 --- a/lib/libc/i386/sys/sbrk.S +++ b/lib/libc/i386/sys/sbrk.S @@ -89,3 +89,5 @@ err: jmp HIDENAME(cerror) #endif /* PIC */ END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/setlogin.S b/lib/libc/i386/sys/setlogin.S index 2a814bd..c6436b5 100644 --- a/lib/libc/i386/sys/setlogin.S +++ b/lib/libc/i386/sys/setlogin.S @@ -53,3 +53,5 @@ SYSCALL(setlogin) #endif ret /* setlogin(name) */ END(__sys_setlogin) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/sigreturn.S b/lib/libc/i386/sys/sigreturn.S index 28dc227..f91816e 100644 --- a/lib/libc/i386/sys/sigreturn.S +++ b/lib/libc/i386/sys/sigreturn.S @@ -44,3 +44,5 @@ __FBSDID("$FreeBSD$"); */ RSYSCALL(sigreturn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/i386/sys/syscall.S b/lib/libc/i386/sys/syscall.S index d26ce47..e5d6e23 100644 --- a/lib/libc/i386/sys/syscall.S +++ b/lib/libc/i386/sys/syscall.S @@ -51,3 +51,5 @@ ENTRY(syscall) PIC_PROLOGUE jmp PIC_PLT(HIDENAME(cerror)) END(syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 09d4016..7a89471 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -56,11 +56,13 @@ CLEANFILES+= ${SASM} ${SPSEUDO} ${SASM}: printf '#include "compat.h"\n' > ${.TARGET} printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' >> ${.TARGET} + printf '\t.section .note.GNU-stack,"",%%progbits\n' >>${.TARGET} ${SPSEUDO}: printf '#include "compat.h"\n' > ${.TARGET} printf '#include "SYS.h"\nPSEUDO(${.PREFIX:S/_//})\n' \ >> ${.TARGET} + printf '\t.section .note.GNU-stack,"",%%progbits\n' >>${.TARGET} MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \ aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \ diff --git a/lib/libcompiler_rt/Makefile b/lib/libcompiler_rt/Makefile index f27dcf5..6e3ebb9 100644 --- a/lib/libcompiler_rt/Makefile +++ b/lib/libcompiler_rt/Makefile @@ -156,4 +156,10 @@ SYMLINKS+=libcompiler_rt_p.a ${LIBDIR}/libgcc_p.a . endif .endif +.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +AFLAGS+=--noexecstack +ACFLAGS+=-Wl,a,--noexecstack +.endif + + .include diff --git a/lib/libthr/arch/amd64/amd64/_umtx_op_err.S b/lib/libthr/arch/amd64/amd64/_umtx_op_err.S index d11753d..b54fe64 100644 --- a/lib/libthr/arch/amd64/amd64/_umtx_op_err.S +++ b/lib/libthr/arch/amd64/amd64/_umtx_op_err.S @@ -35,3 +35,5 @@ #define KERNCALL movq %rcx, %r10; syscall RSYSCALL_ERR(_umtx_op) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libthr/arch/i386/i386/_umtx_op_err.S b/lib/libthr/arch/i386/i386/_umtx_op_err.S index 9b6f0b0..113412c 100644 --- a/lib/libthr/arch/i386/i386/_umtx_op_err.S +++ b/lib/libthr/arch/i386/i386/_umtx_op_err.S @@ -34,3 +34,5 @@ mov __CONCAT($SYS_,x),%eax; int $0x80; ret SYSCALL_ERR(_umtx_op) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index 5e36239..9f82a1b 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -382,6 +382,8 @@ FBSDprivate_1.0 { _thread_size_key; _thread_state_running; _thread_state_zoombie; + + __pthread_map_stacks_exec; }; FBSD_1.1 { diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index f0af20b..a41b33f 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, sigset_t set, oset; cpuset_t *cpusetp = NULL; int cpusetsize = 0; + int old_stack_prot; _thr_check_init(); @@ -96,6 +98,7 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, new_thread->tid = TID_TERMINATED; + old_stack_prot = _rtld_get_stack_prot(); if (create_stack(&new_thread->attr) != 0) { /* Insufficient memory to create a stack: */ _thr_free(curthread, new_thread); @@ -130,6 +133,14 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, /* Add the new thread. */ new_thread->refcount = 1; _thr_link(curthread, new_thread); + + /* + * Handle the race between __pthread_map_stacks_exec and + * thread linkage. + */ + if (old_stack_prot != _rtld_get_stack_prot()) + _thr_stack_fix_protection(new_thread); + /* Return thread pointer eariler so that new thread can use it. */ (*thread) = new_thread; if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) { diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 9df97aa..9b9227b 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -898,6 +898,7 @@ struct dl_phdr_info; void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info); void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden; +void _thr_stack_fix_protection(struct pthread *thrd); __END_DECLS diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c index e6af702..1821859 100644 --- a/lib/libthr/thread/thr_rtld.c +++ b/lib/libthr/thread/thr_rtld.c @@ -31,6 +31,7 @@ * A lockless rwlock for rtld. */ #include +#include #include #include @@ -194,6 +195,8 @@ _thr_rtld_init(void) /* force to resolve memcpy PLT */ memcpy(&dummy, &dummy, sizeof(dummy)); + mprotect(NULL, 0, 0); + li.lock_create = _thr_rtld_lock_create; li.lock_destroy = _thr_rtld_lock_destroy; li.rlock_acquire = _thr_rtld_rlock_acquire; diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c index 7684953..3ff4afe 100644 --- a/lib/libthr/thread/thr_stack.c +++ b/lib/libthr/thread/thr_stack.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "thr_private.h" @@ -128,6 +129,36 @@ round_up(size_t size) return size; } +void +_thr_stack_fix_protection(struct pthread *thrd) +{ + + mprotect((char *)thrd->attr.stackaddr_attr + + round_up(thrd->attr.guardsize_attr), + round_up(thrd->attr.stacksize_attr), + _rtld_get_stack_prot()); +} + +void __pthread_map_stacks_exec(void); +void +__pthread_map_stacks_exec(void) +{ + struct pthread *curthread, *thrd; + struct stack *st; + + curthread = _get_curthread(); + THREAD_LIST_RDLOCK(curthread); + LIST_FOREACH(st, &mstackq, qe) + mprotect((char *)st->stackaddr + st->guardsize, st->stacksize, + _rtld_get_stack_prot()); + LIST_FOREACH(st, &dstackq, qe) + mprotect((char *)st->stackaddr + st->guardsize, st->stacksize, + _rtld_get_stack_prot()); + TAILQ_FOREACH(thrd, &_thread_list, tle) + _thr_stack_fix_protection(thrd); + THREAD_LIST_UNLOCK(curthread); +} + int _thr_stack_alloc(struct pthread_attr *attr) { @@ -210,7 +241,7 @@ _thr_stack_alloc(struct pthread_attr *attr) /* Map the stack and guard page together, and split guard page from allocated space: */ if ((stackaddr = mmap(stackaddr, stacksize+guardsize, - PROT_READ | PROT_WRITE, MAP_STACK, + _rtld_get_stack_prot(), MAP_STACK, -1, 0)) != MAP_FAILED && (guardsize == 0 || mprotect(stackaddr, guardsize, PROT_NONE) == 0)) { diff --git a/lib/msun/amd64/e_remainder.S b/lib/msun/amd64/e_remainder.S index 6d87a93..6c7f6d3fc 100644 --- a/lib/msun/amd64/e_remainder.S +++ b/lib/msun/amd64/e_remainder.S @@ -51,3 +51,5 @@ ENTRY(remainder) movsd -8(%rsp),%xmm0 fstp %st ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/e_remainderf.S b/lib/msun/amd64/e_remainderf.S index ad3b59e..3b6e885 100644 --- a/lib/msun/amd64/e_remainderf.S +++ b/lib/msun/amd64/e_remainderf.S @@ -21,3 +21,5 @@ ENTRY(remainderf) movss -4(%rsp),%xmm0 fstp %st ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/e_remainderl.S b/lib/msun/amd64/e_remainderl.S index 05b9682..56566b5 100644 --- a/lib/msun/amd64/e_remainderl.S +++ b/lib/msun/amd64/e_remainderl.S @@ -46,3 +46,5 @@ ENTRY(remainderl) jne 1b fstp %st(1) ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/e_sqrt.S b/lib/msun/amd64/e_sqrt.S index 4129320..6f9eeff 100644 --- a/lib/msun/amd64/e_sqrt.S +++ b/lib/msun/amd64/e_sqrt.S @@ -32,3 +32,5 @@ ENTRY(sqrt) ret END(sqrt) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/e_sqrtf.S b/lib/msun/amd64/e_sqrtf.S index 4dc2eb3..25df7b1 100644 --- a/lib/msun/amd64/e_sqrtf.S +++ b/lib/msun/amd64/e_sqrtf.S @@ -31,3 +31,5 @@ ENTRY(sqrtf) sqrtss %xmm0, %xmm0 ret END(sqrtf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/e_sqrtl.S b/lib/msun/amd64/e_sqrtl.S index bbc7abe..b7064a7 100644 --- a/lib/msun/amd64/e_sqrtl.S +++ b/lib/msun/amd64/e_sqrtl.S @@ -31,3 +31,5 @@ ENTRY(sqrtl) fldt 8(%rsp) fsqrt ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_llrint.S b/lib/msun/amd64/s_llrint.S index ab09846..6cb91e6 100644 --- a/lib/msun/amd64/s_llrint.S +++ b/lib/msun/amd64/s_llrint.S @@ -4,3 +4,5 @@ __FBSDID("$FreeBSD$") /* sizeof(long) == sizeof(long long) */ #define fn llrint #include "s_lrint.S" + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_llrintf.S b/lib/msun/amd64/s_llrintf.S index e810e40..d73ea89 100644 --- a/lib/msun/amd64/s_llrintf.S +++ b/lib/msun/amd64/s_llrintf.S @@ -4,3 +4,5 @@ __FBSDID("$FreeBSD$") /* sizeof(long) == sizeof(long long) */ #define fn llrintf #include "s_lrintf.S" + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_llrintl.S b/lib/msun/amd64/s_llrintl.S index a0e4f2b..1aedff0 100644 --- a/lib/msun/amd64/s_llrintl.S +++ b/lib/msun/amd64/s_llrintl.S @@ -33,3 +33,5 @@ ENTRY(llrintl) fistpll (%rsp) popq %rax ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_logbl.S b/lib/msun/amd64/s_logbl.S index bafb0e8..370af7c 100644 --- a/lib/msun/amd64/s_logbl.S +++ b/lib/msun/amd64/s_logbl.S @@ -41,3 +41,5 @@ ENTRY(logbl) fxtract fstp %st ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_lrint.S b/lib/msun/amd64/s_lrint.S index 975ab9e..5a5d285 100644 --- a/lib/msun/amd64/s_lrint.S +++ b/lib/msun/amd64/s_lrint.S @@ -35,3 +35,5 @@ ENTRY(fn) cvtsd2si %xmm0, %rax ret END(fn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_lrintf.S b/lib/msun/amd64/s_lrintf.S index f55126c..0c25a7f 100644 --- a/lib/msun/amd64/s_lrintf.S +++ b/lib/msun/amd64/s_lrintf.S @@ -35,3 +35,5 @@ ENTRY(fn) cvtss2si %xmm0, %rax ret END(fn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_lrintl.S b/lib/msun/amd64/s_lrintl.S index 5e85cff..58e56c4 100644 --- a/lib/msun/amd64/s_lrintl.S +++ b/lib/msun/amd64/s_lrintl.S @@ -33,3 +33,5 @@ ENTRY(lrintl) fistpll (%rsp) popq %rax ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_remquo.S b/lib/msun/amd64/s_remquo.S index 6d821d9..f000c36 100644 --- a/lib/msun/amd64/s_remquo.S +++ b/lib/msun/amd64/s_remquo.S @@ -64,3 +64,5 @@ ENTRY(remquo) movsd -8(%rsp),%xmm0 ret END(remquo) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_remquof.S b/lib/msun/amd64/s_remquof.S index 24d728c..3b2cd2d 100644 --- a/lib/msun/amd64/s_remquof.S +++ b/lib/msun/amd64/s_remquof.S @@ -64,3 +64,5 @@ ENTRY(remquof) movss -4(%rsp),%xmm0 ret END(remquof) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_remquol.S b/lib/msun/amd64/s_remquol.S index e2d76b2..9631efd 100644 --- a/lib/msun/amd64/s_remquol.S +++ b/lib/msun/amd64/s_remquol.S @@ -60,3 +60,5 @@ ENTRY(remquol) /* Store the quotient and return. */ movl %eax,(%rdi) ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_rintl.S b/lib/msun/amd64/s_rintl.S index 9b9a22d..c7eb512 100644 --- a/lib/msun/amd64/s_rintl.S +++ b/lib/msun/amd64/s_rintl.S @@ -41,3 +41,5 @@ ENTRY(rintl) fldt 8(%rsp) frndint ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_scalbn.S b/lib/msun/amd64/s_scalbn.S index 5275ba7..3dc25ad 100644 --- a/lib/msun/amd64/s_scalbn.S +++ b/lib/msun/amd64/s_scalbn.S @@ -38,3 +38,5 @@ ENTRY(scalbn) movsd -8(%rsp),%xmm0 ret END(scalbn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_scalbnf.S b/lib/msun/amd64/s_scalbnf.S index 2a794da..5ab4eec 100644 --- a/lib/msun/amd64/s_scalbnf.S +++ b/lib/msun/amd64/s_scalbnf.S @@ -41,3 +41,5 @@ END(scalbnf) .globl CNAME(ldexpf) .set CNAME(ldexpf),CNAME(scalbnf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/amd64/s_scalbnl.S b/lib/msun/amd64/s_scalbnl.S index 95bbe9f..021d329 100644 --- a/lib/msun/amd64/s_scalbnl.S +++ b/lib/msun/amd64/s_scalbnl.S @@ -18,3 +18,5 @@ END(scalbnl) .globl CNAME(ldexpl) .set CNAME(ldexpl),CNAME(scalbnl) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_exp.S b/lib/msun/i387/e_exp.S index d7a738b..a89ba42 100644 --- a/lib/msun/i387/e_exp.S +++ b/lib/msun/i387/e_exp.S @@ -96,3 +96,5 @@ x_not_minus_Inf: fldl 4(%esp) ret END(exp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_fmod.S b/lib/msun/i387/e_fmod.S index 6742813..421cbba 100644 --- a/lib/msun/i387/e_fmod.S +++ b/lib/msun/i387/e_fmod.S @@ -46,3 +46,5 @@ ENTRY(fmod) fstp %st(1) ret END(fmod) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_log.S b/lib/msun/i387/e_log.S index 8ec2db6..103e118 100644 --- a/lib/msun/i387/e_log.S +++ b/lib/msun/i387/e_log.S @@ -42,3 +42,5 @@ ENTRY(log) fyl2x ret END(log) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_log10.S b/lib/msun/i387/e_log10.S index fef5b40..6ab4a5d 100644 --- a/lib/msun/i387/e_log10.S +++ b/lib/msun/i387/e_log10.S @@ -42,3 +42,5 @@ ENTRY(log10) fyl2x ret END(log10) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_log10f.S b/lib/msun/i387/e_log10f.S index 3c3271f..fc75674 100644 --- a/lib/msun/i387/e_log10f.S +++ b/lib/msun/i387/e_log10f.S @@ -14,3 +14,5 @@ ENTRY(log10f) fyl2x ret END(log10f) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_logf.S b/lib/msun/i387/e_logf.S index e66c844..51f12e7 100644 --- a/lib/msun/i387/e_logf.S +++ b/lib/msun/i387/e_logf.S @@ -13,3 +13,5 @@ ENTRY(logf) flds 4(%esp) fyl2x ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_remainder.S b/lib/msun/i387/e_remainder.S index e92e748..0be8638 100644 --- a/lib/msun/i387/e_remainder.S +++ b/lib/msun/i387/e_remainder.S @@ -46,3 +46,5 @@ ENTRY(remainder) fstp %st(1) ret END(remainder) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_remainderf.S b/lib/msun/i387/e_remainderf.S index 9d760d5..38987e5 100644 --- a/lib/msun/i387/e_remainderf.S +++ b/lib/msun/i387/e_remainderf.S @@ -18,3 +18,5 @@ ENTRY(remainderf) fstp %st(1) ret END(remainderf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_remainderl.S b/lib/msun/i387/e_remainderl.S index f5f8197..bdbd2ba 100644 --- a/lib/msun/i387/e_remainderl.S +++ b/lib/msun/i387/e_remainderl.S @@ -46,3 +46,5 @@ ENTRY(remainderl) jp 1b fstp %st(1) ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_sqrt.S b/lib/msun/i387/e_sqrt.S index c2190ae..8581439 100644 --- a/lib/msun/i387/e_sqrt.S +++ b/lib/msun/i387/e_sqrt.S @@ -41,3 +41,5 @@ ENTRY(sqrt) fsqrt ret END(sqrt) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_sqrtf.S b/lib/msun/i387/e_sqrtf.S index dbb64f6..75a9ae2 100644 --- a/lib/msun/i387/e_sqrtf.S +++ b/lib/msun/i387/e_sqrtf.S @@ -13,3 +13,5 @@ ENTRY(sqrtf) fsqrt ret END(sqrtf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/e_sqrtl.S b/lib/msun/i387/e_sqrtl.S index a96fd04..3a5ef3e 100644 --- a/lib/msun/i387/e_sqrtl.S +++ b/lib/msun/i387/e_sqrtl.S @@ -40,3 +40,5 @@ ENTRY(sqrtl) fldt 4(%esp) fsqrt ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_ceil.S b/lib/msun/i387/s_ceil.S index dbc2c68..7e099b0 100644 --- a/lib/msun/i387/s_ceil.S +++ b/lib/msun/i387/s_ceil.S @@ -56,3 +56,5 @@ ENTRY(ceil) leave ret END(ceil) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_ceilf.S b/lib/msun/i387/s_ceilf.S index 846028f..e9009c3 100644 --- a/lib/msun/i387/s_ceilf.S +++ b/lib/msun/i387/s_ceilf.S @@ -28,3 +28,5 @@ ENTRY(ceilf) leave ret END(ceilf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_ceill.S b/lib/msun/i387/s_ceill.S index 9466a3e..184ef18 100644 --- a/lib/msun/i387/s_ceill.S +++ b/lib/msun/i387/s_ceill.S @@ -26,3 +26,5 @@ ENTRY(ceill) leave ret END(ceill) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_copysign.S b/lib/msun/i387/s_copysign.S index 4fa1ecc..63a916f 100644 --- a/lib/msun/i387/s_copysign.S +++ b/lib/msun/i387/s_copysign.S @@ -46,3 +46,5 @@ ENTRY(copysign) fldl 4(%esp) ret END(copysign) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_copysignf.S b/lib/msun/i387/s_copysignf.S index 0be7a65..7ad1a64 100644 --- a/lib/msun/i387/s_copysignf.S +++ b/lib/msun/i387/s_copysignf.S @@ -18,3 +18,5 @@ ENTRY(copysignf) flds 4(%esp) ret END(copysignf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_copysignl.S b/lib/msun/i387/s_copysignl.S index 5256628..b4143c0 100644 --- a/lib/msun/i387/s_copysignl.S +++ b/lib/msun/i387/s_copysignl.S @@ -16,3 +16,5 @@ ENTRY(copysignl) fldt 4(%esp) ret END(copysignl) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_cos.S b/lib/msun/i387/s_cos.S index 3e96711..9c3f2ca 100644 --- a/lib/msun/i387/s_cos.S +++ b/lib/msun/i387/s_cos.S @@ -54,3 +54,5 @@ ENTRY(cos) fcos ret END(cos) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_finite.S b/lib/msun/i387/s_finite.S index b09ca9b..0107856 100644 --- a/lib/msun/i387/s_finite.S +++ b/lib/msun/i387/s_finite.S @@ -44,3 +44,5 @@ ENTRY(finite) andl $0x000000ff, %eax ret END(finite) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_floor.S b/lib/msun/i387/s_floor.S index 38f99bf..a06c66e 100644 --- a/lib/msun/i387/s_floor.S +++ b/lib/msun/i387/s_floor.S @@ -56,3 +56,5 @@ ENTRY(floor) leave ret END(floor) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_floorf.S b/lib/msun/i387/s_floorf.S index 14d3b85..e758d05 100644 --- a/lib/msun/i387/s_floorf.S +++ b/lib/msun/i387/s_floorf.S @@ -28,3 +28,5 @@ ENTRY(floorf) leave ret END(floorf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_floorl.S b/lib/msun/i387/s_floorl.S index bec03a7..cbb05f0 100644 --- a/lib/msun/i387/s_floorl.S +++ b/lib/msun/i387/s_floorl.S @@ -26,3 +26,5 @@ ENTRY(floorl) leave ret END(floorl) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_llrint.S b/lib/msun/i387/s_llrint.S index 2bf1342..ded12a7 100644 --- a/lib/msun/i387/s_llrint.S +++ b/lib/msun/i387/s_llrint.S @@ -35,3 +35,5 @@ ENTRY(llrint) popl %edx ret END(llrint) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_llrintf.S b/lib/msun/i387/s_llrintf.S index 465e407..4372b7d 100644 --- a/lib/msun/i387/s_llrintf.S +++ b/lib/msun/i387/s_llrintf.S @@ -35,3 +35,5 @@ ENTRY(llrintf) popl %edx ret END(llrintf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_llrintl.S b/lib/msun/i387/s_llrintl.S index 96d2c6b..0fe97b8 100644 --- a/lib/msun/i387/s_llrintl.S +++ b/lib/msun/i387/s_llrintl.S @@ -34,3 +34,5 @@ ENTRY(llrintl) popl %eax popl %edx ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_logb.S b/lib/msun/i387/s_logb.S index 0e82b87..8304aa2 100644 --- a/lib/msun/i387/s_logb.S +++ b/lib/msun/i387/s_logb.S @@ -42,3 +42,5 @@ ENTRY(logb) fstp %st ret END(logb) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_logbf.S b/lib/msun/i387/s_logbf.S index ddd5eba..960f6f1 100644 --- a/lib/msun/i387/s_logbf.S +++ b/lib/msun/i387/s_logbf.S @@ -14,3 +14,5 @@ ENTRY(logbf) fstp %st ret END(logbf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_logbl.S b/lib/msun/i387/s_logbl.S index dc48b99..685da94 100644 --- a/lib/msun/i387/s_logbl.S +++ b/lib/msun/i387/s_logbl.S @@ -41,3 +41,5 @@ ENTRY(logbl) fxtract fstp %st ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_lrint.S b/lib/msun/i387/s_lrint.S index 10db333..e138c52 100644 --- a/lib/msun/i387/s_lrint.S +++ b/lib/msun/i387/s_lrint.S @@ -34,3 +34,5 @@ ENTRY(lrint) popl %eax ret END(lrint) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_lrintf.S b/lib/msun/i387/s_lrintf.S index ee97206..7571b7f 100644 --- a/lib/msun/i387/s_lrintf.S +++ b/lib/msun/i387/s_lrintf.S @@ -34,3 +34,5 @@ ENTRY(lrintf) popl %eax ret END(lrintf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_lrintl.S b/lib/msun/i387/s_lrintl.S index f2ff5380..fb7f261 100644 --- a/lib/msun/i387/s_lrintl.S +++ b/lib/msun/i387/s_lrintl.S @@ -33,3 +33,5 @@ ENTRY(lrintl) fistpl (%esp) popl %eax ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_remquo.S b/lib/msun/i387/s_remquo.S index b71dd6f..5fc4388 100644 --- a/lib/msun/i387/s_remquo.S +++ b/lib/msun/i387/s_remquo.S @@ -61,3 +61,5 @@ ENTRY(remquo) movl %eax,(%ecx) ret END(remquo) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_remquof.S b/lib/msun/i387/s_remquof.S index c0b37fc..32ee399 100644 --- a/lib/msun/i387/s_remquof.S +++ b/lib/msun/i387/s_remquof.S @@ -61,3 +61,5 @@ ENTRY(remquof) movl %eax,(%ecx) ret END(remquof) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_remquol.S b/lib/msun/i387/s_remquol.S index 64e532c..df149df 100644 --- a/lib/msun/i387/s_remquol.S +++ b/lib/msun/i387/s_remquol.S @@ -61,3 +61,5 @@ ENTRY(remquol) movl 28(%esp),%ecx movl %eax,(%ecx) ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_rint.S b/lib/msun/i387/s_rint.S index 0f5e348..130819b 100644 --- a/lib/msun/i387/s_rint.S +++ b/lib/msun/i387/s_rint.S @@ -41,3 +41,5 @@ ENTRY(rint) frndint ret END(rint) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_rintf.S b/lib/msun/i387/s_rintf.S index 2f17520..e188ae4 100644 --- a/lib/msun/i387/s_rintf.S +++ b/lib/msun/i387/s_rintf.S @@ -13,3 +13,5 @@ ENTRY(rintf) frndint ret END(rintf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_rintl.S b/lib/msun/i387/s_rintl.S index 90ba6a6..edb9573 100644 --- a/lib/msun/i387/s_rintl.S +++ b/lib/msun/i387/s_rintl.S @@ -40,3 +40,5 @@ ENTRY(rintl) fldt 4(%esp) frndint ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_scalbn.S b/lib/msun/i387/s_scalbn.S index 9996ee5..94d73e4 100644 --- a/lib/msun/i387/s_scalbn.S +++ b/lib/msun/i387/s_scalbn.S @@ -43,3 +43,5 @@ ENTRY(scalbn) fstp %st(1) ret END(scalbn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_scalbnf.S b/lib/msun/i387/s_scalbnf.S index df21521..d61888b 100644 --- a/lib/msun/i387/s_scalbnf.S +++ b/lib/msun/i387/s_scalbnf.S @@ -18,3 +18,5 @@ END(scalbnf) .globl CNAME(ldexpf) .set CNAME(ldexpf),CNAME(scalbnf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_scalbnl.S b/lib/msun/i387/s_scalbnl.S index 4ac6877..3881f81 100644 --- a/lib/msun/i387/s_scalbnl.S +++ b/lib/msun/i387/s_scalbnl.S @@ -18,3 +18,5 @@ END(scalbnl) .globl CNAME(ldexpl) .set CNAME(ldexpl),CNAME(scalbnl) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_significand.S b/lib/msun/i387/s_significand.S index d9c58d5..ac0ffcf 100644 --- a/lib/msun/i387/s_significand.S +++ b/lib/msun/i387/s_significand.S @@ -42,3 +42,5 @@ ENTRY(significand) fstp %st(1) ret END(significand) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_significandf.S b/lib/msun/i387/s_significandf.S index e8f8b9a..985ad97 100644 --- a/lib/msun/i387/s_significandf.S +++ b/lib/msun/i387/s_significandf.S @@ -14,3 +14,5 @@ ENTRY(significandf) fstp %st(1) ret END(significandf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_sin.S b/lib/msun/i387/s_sin.S index 8b6f2d2..11c4d63 100644 --- a/lib/msun/i387/s_sin.S +++ b/lib/msun/i387/s_sin.S @@ -54,3 +54,5 @@ ENTRY(sin) fsin ret END(sin) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_tan.S b/lib/msun/i387/s_tan.S index a2edd45..e31ebdf 100644 --- a/lib/msun/i387/s_tan.S +++ b/lib/msun/i387/s_tan.S @@ -56,3 +56,5 @@ ENTRY(tan) fstp %st(0) ret END(tan) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_trunc.S b/lib/msun/i387/s_trunc.S index ac16e69..0a9ad41 100644 --- a/lib/msun/i387/s_trunc.S +++ b/lib/msun/i387/s_trunc.S @@ -25,3 +25,5 @@ ENTRY(trunc) leave ret END(trunc) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_truncf.S b/lib/msun/i387/s_truncf.S index ccc84ae..0583dc8 100644 --- a/lib/msun/i387/s_truncf.S +++ b/lib/msun/i387/s_truncf.S @@ -25,3 +25,5 @@ ENTRY(truncf) leave ret END(truncf) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/i387/s_truncl.S b/lib/msun/i387/s_truncl.S index abbca8f..c3815ad 100644 --- a/lib/msun/i387/s_truncl.S +++ b/lib/msun/i387/s_truncl.S @@ -25,3 +25,5 @@ ENTRY(truncl) leave ret END(truncl) + + .section .note.GNU-stack,"",%progbits diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map index 7a8273f..6a416a7 100644 --- a/libexec/rtld-elf/Symbol.map +++ b/libexec/rtld-elf/Symbol.map @@ -28,4 +28,5 @@ FBSDprivate_1.0 { _rtld_atfork_pre; _rtld_atfork_post; _rtld_addr_phdr; + _rtld_get_stack_prot; }; diff --git a/libexec/rtld-elf/amd64/rtld_start.S b/libexec/rtld-elf/amd64/rtld_start.S index 4cdad22..a63d94c 100644 --- a/libexec/rtld-elf/amd64/rtld_start.S +++ b/libexec/rtld-elf/amd64/rtld_start.S @@ -112,3 +112,5 @@ _rtld_bind_start: popfq # Restore rflags leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags ret # "Return" to target address + + .section .note.GNU-stack,"",%progbits diff --git a/libexec/rtld-elf/i386/rtld_start.S b/libexec/rtld-elf/i386/rtld_start.S index 9a6e2d5..482e51a 100644 --- a/libexec/rtld-elf/i386/rtld_start.S +++ b/libexec/rtld-elf/i386/rtld_start.S @@ -89,3 +89,5 @@ _rtld_bind_start: popf # Restore eflags leal 4(%esp),%esp # Discard reloff, do not change eflags ret # "Return" to target address + + .section .note.GNU-stack,"",%progbits 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; } diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index ee3985b..2e39b67 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -103,6 +103,7 @@ static void unload_filtees(Obj_Entry *); static int load_needed_objects(Obj_Entry *, int); static int load_preload_objects(void); static Obj_Entry *load_object(const char *, const Obj_Entry *, int); +static void map_stacks_exec(void); static Obj_Entry *obj_from_addr(const void *); static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *); static void objlist_call_init(Objlist *, RtldLockState *); @@ -188,6 +189,9 @@ extern Elf_Dyn _DYNAMIC; int osreldate, pagesize; +static int stack_prot = PROT_READ | PROT_WRITE | PROT_EXEC; +static int max_stack_flags; + /* * Global declarations normally provided by crt1. The dynamic linker is * not built with crt1, so we have to provide them ourselves. @@ -382,6 +386,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) close(fd); if (obj_main == NULL) die(); + max_stack_flags = obj->stack_flags; } else { /* Main program already loaded. */ const Elf_Phdr *phdr; int phnum; @@ -421,6 +426,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) dbg("obj_main path %s", obj_main->path); obj_main->mainprog = true; + if (aux_info[AT_STACKPROT] != NULL && + aux_info[AT_STACKPROT]->a_un.a_val != 0) + stack_prot = aux_info[AT_STACKPROT]->a_un.a_val; + /* * Get the actual dynamic linker pathname from the executable if * possible. (It should always be possible.) That ensures that @@ -519,6 +528,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */ + map_stacks_exec(); + wlock_acquire(rtld_bind_lock, &lockstate); objlist_call_init(&initlist, &lockstate); objlist_clear(&initlist); @@ -1031,6 +1042,8 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) break; } + obj->stack_flags = PF_X | PF_R | PF_W; + for (ph = phdr; ph < phlimit; ph++) { switch (ph->p_type) { @@ -1062,6 +1075,10 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) obj->tlsinitsize = ph->p_filesz; obj->tlsinit = (void*)(ph->p_vaddr + obj->relocbase); break; + + case PT_GNU_STACK: + obj->stack_flags = ph->p_flags; + break; } } if (nsegs < 1) { @@ -1679,6 +1696,7 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp, obj_count++; obj_loads++; linkmap_add(obj); /* for GDB & dlinfo() */ + max_stack_flags |= obj->stack_flags; dbg(" %p .. %p: %s", obj->mapbase, obj->mapbase + obj->mapsize - 1, obj->path); @@ -2202,6 +2220,8 @@ dlopen_object(const char *name, Obj_Entry *refobj, int lo_flags, int mode) name); GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL); + map_stacks_exec(); + /* Call the init functions. */ objlist_call_init(&initlist, &lockstate); objlist_clear(&initlist); @@ -3872,6 +3892,28 @@ fetch_ventry(const Obj_Entry *obj, unsigned long symnum) return NULL; } +int +_rtld_get_stack_prot(void) +{ + + return (stack_prot); +} + +static void +map_stacks_exec(void) +{ + void (*thr_map_stacks_exec)(void); + + if ((max_stack_flags & PF_X) == 0 || (stack_prot & PROT_EXEC) != 0) + return; + thr_map_stacks_exec = (void (*)(void))(uintptr_t) + get_program_var_addr("__pthread_map_stacks_exec"); + if (thr_map_stacks_exec != NULL) { + stack_prot |= PROT_EXEC; + thr_map_stacks_exec(); + } +} + void symlook_init(SymLook *dst, const char *name) { diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index b70e8b6..8941d29 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -157,6 +157,7 @@ typedef struct Struct_Obj_Entry { const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ size_t phsize; /* Size of program header in bytes */ const char *interp; /* Pathname of the interpreter, if any */ + Elf_Word stack_flags; /* TLS information */ int tlsindex; /* Index in DTV for this module */ diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index 4da0a2f..bef1cbe 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -120,26 +120,27 @@ PO_FLAG=-pg ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) .asm.po: - ${CC} -x assembler-with-cpp -DPROF ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CC} -x assembler-with-cpp -DPROF ${PO_CFLAGS} ${ACFLAGS} \ + -c ${.IMPSRC} -o ${.TARGET} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) .asm.So: - ${CC} -x assembler-with-cpp ${PICFLAG} -DPIC ${CFLAGS} \ + ${CC} -x assembler-with-cpp ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \ -c ${.IMPSRC} -o ${.TARGET} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) .S.po: - ${CC} -DPROF ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CC} -DPROF ${PO_CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) .S.So: - ${CC} ${PICFLAG} -DPIC ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CC} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) diff --git a/share/mk/sys.mk b/share/mk/sys.mk index e6368ba..a4b429b 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -41,6 +41,7 @@ RANLIB ?= ranlib AS ?= as AFLAGS ?= +ACFLAGS ?= .if defined(%POSIX) CC ?= c89 @@ -275,13 +276,13 @@ YFLAGS ?= -d ${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} -c ${.IMPSRC} .S.o: - ${CC} ${CFLAGS} -c ${.IMPSRC} + ${CC} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) .asm.o: - ${CC} -x assembler-with-cpp ${CFLAGS} -c ${.IMPSRC} + ${CC} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || \ (${ECHO} ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} && \ ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}) diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index 6472d55..fbcf8726 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -79,6 +79,8 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_set_syscall_retval = cpu_set_syscall_retval, .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, + .sv_shared_page_base = SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, }; static Elf64_Brandinfo freebsd_brand_info = { @@ -129,6 +131,19 @@ SYSINIT(kelf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf64_insert_brand_entry, &kfreebsd_brand_info); +static void +elf64_shared_page_init(void *dummy) +{ + + elf64_freebsd_sysvec.sv_shared_page_obj = shared_page_obj; + elf64_freebsd_sysvec.sv_sigcode_base = + elf64_freebsd_sysvec.sv_shared_page_base + + shared_page_fill(*elf64_freebsd_sysvec.sv_szsigcode, 16, + elf64_freebsd_sysvec.sv_sigcode); +} + +SYSINIT(shp64, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t)elf64_shared_page_init, NULL); void elf64_dump_thread(struct thread *td __unused, void *dst __unused, diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 6c946e6..72e0fd7 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -386,7 +386,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } regs->tf_rsp = (long)sfp; - regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); + regs->tf_rip = p->p_sysent->sv_sigcode_base; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c index 808790b..91884d2 100644 --- a/sys/amd64/ia32/ia32_signal.c +++ b/sys/amd64/ia32/ia32_signal.c @@ -393,7 +393,8 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } regs->tf_rsp = (uintptr_t)sfp; - regs->tf_rip = p->p_sysent->sv_psstrings - sz_freebsd4_ia32_sigcode; + regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode - + sz_freebsd4_ia32_sigcode; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -514,7 +515,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) } regs->tf_rsp = (uintptr_t)sfp; - regs->tf_rip = p->p_sysent->sv_psstrings - *(p->p_sysent->sv_szsigcode); + regs->tf_rip = p->p_sysent->sv_sigcode_base; regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; diff --git a/sys/amd64/include/elf.h b/sys/amd64/include/elf.h index 1f5c754..ded4e44 100644 --- a/sys/amd64/include/elf.h +++ b/sys/amd64/include/elf.h @@ -94,8 +94,9 @@ __ElfType(Auxinfo); #define AT_NCPUS 19 /* Number of CPUs. */ #define AT_PAGESIZES 20 /* Pagesizes. */ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ +#define AT_STACKPROT 23 /* Initial stack protection. */ -#define AT_COUNT 22 /* Count of defined aux entry types. */ +#define AT_COUNT 24 /* Count of defined aux entry types. */ /* * Relocation types. diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 7a50c59..88d68b9 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -186,7 +186,8 @@ #define VM_MAXUSER_ADDRESS UVADDR(NUPML4E, 0, 0, 0) -#define USRSTACK VM_MAXUSER_ADDRESS +#define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) +#define USRSTACK SHAREDPAGE #define VM_MAX_ADDRESS UPT_MAX_ADDRESS #define VM_MIN_ADDRESS (0) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 326cf031..cf3af87 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2546,7 +2546,10 @@ freebsd32_copyout_strings(struct image_params *imgp) execpath_len = 0; arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent-> sv_psstrings; - szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); + if (imgp->proc->p_sysent->sv_sigcode_base == 0) + szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); + else + szsigcode = 0; destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - roundup(execpath_len, sizeof(char *)) - roundup(sizeof(canary), sizeof(char *)) - @@ -2556,7 +2559,7 @@ freebsd32_copyout_strings(struct image_params *imgp) /* * install sigcode */ - if (szsigcode) + if (szsigcode != 0) copyout(imgp->proc->p_sysent->sv_sigcode, ((caddr_t)arginfo - szsigcode), szsigcode); diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index d7ac5d0..19dfab7 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -129,7 +129,7 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_minsigstksz = MINSIGSTKSZ, .sv_pagesize = IA32_PAGE_SIZE, .sv_minuser = 0, - .sv_maxuser = FREEBSD32_USRSTACK, + .sv_maxuser = FREEBSD32_MAXUSER, .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, .sv_stackprot = VM_PROT_ALL, @@ -141,6 +141,8 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_set_syscall_retval = ia32_set_syscall_retval, .sv_fetch_syscall_args = ia32_fetch_syscall_args, .sv_syscallnames = freebsd32_syscallnames, + .sv_shared_page_base = FREEBSD32_SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, }; @@ -191,6 +193,19 @@ SYSINIT(kia32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &kia32_brand_info); +static void +ia32_shared_page_init(void *dummy) +{ + + ia32_freebsd_sysvec.sv_shared_page_obj = shared_page_obj; + ia32_freebsd_sysvec.sv_sigcode_base = + ia32_freebsd_sysvec.sv_shared_page_base + + shared_page_fill(*ia32_freebsd_sysvec.sv_szsigcode, 16, + ia32_freebsd_sysvec.sv_sigcode); +} + +SYSINIT(ia32shp, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t)ia32_shared_page_init, NULL); void elf32_dump_thread(struct thread *td __unused, void *dst __unused, diff --git a/sys/compat/ia32/ia32_util.h b/sys/compat/ia32/ia32_util.h index f1cc6ed..3a1fecd 100644 --- a/sys/compat/ia32/ia32_util.h +++ b/sys/compat/ia32/ia32_util.h @@ -41,9 +41,12 @@ #include #ifdef __ia64__ -#define FREEBSD32_USRSTACK ((1ul << 32) - IA32_PAGE_SIZE * 2) +#define FREEBSD32_MAXUSER ((1ul << 32) - IA32_PAGE_SIZE * 2) +#define FREEBSD32_USRSTACK FREEBSD32_MAXUSER #else -#define FREEBSD32_USRSTACK ((1ul << 32) - IA32_PAGE_SIZE) +#define FREEBSD32_MAXUSER ((1ul << 32) - IA32_PAGE_SIZE) +#define FREEBSD32_SHAREDPAGE (FREEBSD32_MAXUSER - IA32_PAGE_SIZE) +#define FREEBSD32_USRSTACK FREEBSD32_SHAREDPAGE #endif #define IA32_PAGE_SIZE 4096 diff --git a/sys/i386/include/elf.h b/sys/i386/include/elf.h index 6490f2a..9427811 100644 --- a/sys/i386/include/elf.h +++ b/sys/i386/include/elf.h @@ -96,8 +96,9 @@ __ElfType(Auxinfo); #define AT_NCPUS 19 /* Number of CPUs. */ #define AT_PAGESIZES 20 /* Pagesizes. */ #define AT_PAGESIZESLEN 21 /* Number of pagesizes. */ +#define AT_STACKPROT 23 /* Initial stack protection. */ -#define AT_COUNT 22 /* Count of defined aux entry types. */ +#define AT_COUNT 24 /* Count of defined aux entry types. */ /* * Relocation types. diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 42f5573..2706683 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -92,6 +92,8 @@ static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note, static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel); static boolean_t __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *checknote, int32_t *osrel); +static vm_prot_t __elfN(trans_prot)(Elf_Word); +static Elf_Word __elfN(untrans_prot)(vm_prot_t); SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0, ""); @@ -113,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) = 1; +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)) @@ -644,14 +651,7 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr, for (i = 0, numsegs = 0; i < hdr->e_phnum; i++) { if (phdr[i].p_type == PT_LOAD && phdr[i].p_memsz != 0) { /* Loadable segment */ - prot = 0; - if (phdr[i].p_flags & PF_X) - prot |= VM_PROT_EXECUTE; - if (phdr[i].p_flags & PF_W) - prot |= VM_PROT_WRITE; - if (phdr[i].p_flags & PF_R) - prot |= VM_PROT_READ; - + prot = __elfN(trans_prot)(phdr[i].p_flags); if ((error = __elfN(load_section)(vmspace, imgp->object, phdr[i].p_offset, (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase, @@ -729,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; } } @@ -792,13 +797,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) case PT_LOAD: /* Loadable segment */ if (phdr[i].p_memsz == 0) break; - prot = 0; - if (phdr[i].p_flags & PF_X) - prot |= VM_PROT_EXECUTE; - if (phdr[i].p_flags & PF_W) - prot |= VM_PROT_WRITE; - if (phdr[i].p_flags & PF_R) - prot |= VM_PROT_READ; + prot = __elfN(trans_prot)(phdr[i].p_flags); #if defined(__ia64__) && __ELF_WORD_SIZE == 32 && defined(IA32_ME_HARDER) /* @@ -983,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); @@ -1173,12 +1174,7 @@ cb_put_phdr(entry, closure) phdr->p_filesz = phdr->p_memsz = entry->end - entry->start; phdr->p_align = PAGE_SIZE; phdr->p_flags = 0; - if (entry->protection & VM_PROT_READ) - phdr->p_flags |= PF_R; - if (entry->protection & VM_PROT_WRITE) - phdr->p_flags |= PF_W; - if (entry->protection & VM_PROT_EXECUTE) - phdr->p_flags |= PF_X; + phdr->p_flags = __elfN(untrans_prot)(entry->protection); phc->offset += phdr->p_filesz; phc->phdr++; @@ -1633,3 +1629,33 @@ compress_core (gzFile file, char *inbuf, char *dest_buf, unsigned int len, return (error); } #endif /* COMPRESS_USER_CORES */ + +static vm_prot_t +__elfN(trans_prot)(Elf_Word flags) +{ + vm_prot_t prot; + + prot = 0; + if (flags & PF_X) + prot |= VM_PROT_EXECUTE; + if (flags & PF_W) + prot |= VM_PROT_WRITE; + if (flags & PF_R) + prot |= VM_PROT_READ; + return (prot); +} + +static Elf_Word +__elfN(untrans_prot)(vm_prot_t prot) +{ + vm_prot_t flags; + + flags = 0; + if (prot & VM_PROT_EXECUTE) + flags |= PF_X; + if (prot & VM_PROT_READ) + flags |= PF_R; + if (prot & VM_PROT_WRITE) + flags |= PF_W; + return (flags); +} diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 1e4d690..a034c49 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -389,6 +389,7 @@ do_execve(td, args, mac_p) imgp->canarylen = 0; imgp->pagesizes = 0; imgp->pagesizeslen = 0; + imgp->stack_prot = 0; #ifdef MAC error = mac_execve_enter(imgp, mac_p); @@ -996,6 +997,7 @@ exec_new_vmspace(imgp, sv) int error; struct proc *p = imgp->proc; struct vmspace *vmspace = p->p_vmspace; + vm_object_t obj; vm_offset_t sv_minuser, stack_addr; vm_map_t map; u_long ssiz; @@ -1029,6 +1031,20 @@ exec_new_vmspace(imgp, sv) map = &vmspace->vm_map; } + /* Map a shared page */ + obj = sv->sv_shared_page_obj; + if (obj != NULL) { + vm_object_reference(obj); + error = vm_map_fixed(map, sv->sv_shared_page_obj, 0, + sv->sv_shared_page_base, sv->sv_shared_page_len, + VM_PROT_READ | VM_PROT_EXECUTE, VM_PROT_ALL, + MAP_COPY_ON_WRITE | MAP_ACC_NO_CHARGE); + if (error) { + vm_object_deallocate(obj); + return (error); + } + } + /* Allocate a new stack */ if (sv->sv_maxssiz != NULL) ssiz = *sv->sv_maxssiz; @@ -1036,7 +1052,8 @@ exec_new_vmspace(imgp, sv) ssiz = maxssiz; stack_addr = sv->sv_usrstack - ssiz; error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz, - sv->sv_stackprot, VM_PROT_ALL, MAP_STACK_GROWS_DOWN); + imgp->stack_prot != 0 ? imgp->stack_prot : sv->sv_stackprot, + VM_PROT_ALL, MAP_STACK_GROWS_DOWN); if (error) return (error); @@ -1208,8 +1225,10 @@ exec_copyout_strings(imgp) p = imgp->proc; szsigcode = 0; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; - if (p->p_sysent->sv_szsigcode != NULL) - szsigcode = *(p->p_sysent->sv_szsigcode); + if (p->p_sysent->sv_sigcode_base == 0) { + if (p->p_sysent->sv_szsigcode != NULL) + szsigcode = *(p->p_sysent->sv_szsigcode); + } destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - roundup(execpath_len, sizeof(char *)) - roundup(sizeof(canary), sizeof(char *)) - @@ -1219,7 +1238,7 @@ exec_copyout_strings(imgp) /* * install sigcode */ - if (szsigcode) + if (szsigcode != 0) copyout(p->p_sysent->sv_sigcode, ((caddr_t)arginfo - szsigcode), szsigcode); @@ -1459,3 +1478,49 @@ exec_unregister(execsw_arg) execsw = newexecsw; return (0); } + +vm_object_t shared_page_obj; +static int shared_page_free; + +int +shared_page_fill(int size, int align, const char *data) +{ + vm_page_t m; + struct sf_buf *s; + vm_offset_t sk; + int res; + + if (roundup(shared_page_free, align) + size >= + IDX_TO_OFF(shared_page_obj->size)) + return (-1); + VM_OBJECT_LOCK(shared_page_obj); + m = vm_page_grab(shared_page_obj, 0, VM_ALLOC_RETRY); + s = sf_buf_alloc(m, SFB_DEFAULT); + sk = sf_buf_kva(s); + res = roundup(shared_page_free, align); + bcopy(data, (void *)(sk + shared_page_free), size); + shared_page_free = res + size; + sf_buf_free(s); + vm_page_dirty(m); + vm_page_wakeup(m); + VM_OBJECT_UNLOCK(shared_page_obj); + return (res); +} + +static void +shared_page_init(void *dummy __unused) +{ + vm_page_t m; + + shared_page_obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE, + VM_PROT_DEFAULT, 0, NULL); + VM_OBJECT_LOCK(shared_page_obj); + m = vm_page_grab(shared_page_obj, 0, VM_ALLOC_RETRY | VM_ALLOC_ZERO); + m->valid = VM_PAGE_BITS_ALL; + vm_page_dirty(m); + vm_page_wakeup(m); + VM_OBJECT_UNLOCK(shared_page_obj); +} + +SYSINIT(shp, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t)shared_page_init, + NULL); diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h index b54815f..17cfcc2 100644 --- a/sys/sys/imgact.h +++ b/sys/sys/imgact.h @@ -34,6 +34,8 @@ #include +#include + #define MAXSHELLCMDLEN PAGE_SIZE struct image_args { @@ -75,6 +77,7 @@ struct image_params { int canarylen; unsigned long pagesizes; int pagesizeslen; + vm_prot_t stack_prot; }; #ifdef _KERNEL diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h index 93fe1de..45b9430 100644 --- a/sys/sys/link_elf.h +++ b/sys/sys/link_elf.h @@ -93,6 +93,7 @@ __BEGIN_DECLS typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *); extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *); int _rtld_addr_phdr(const void *, struct dl_phdr_info *); +int _rtld_get_stack_prot(void); __END_DECLS diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index e726fce..735993a 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -116,12 +116,17 @@ struct sysentvec { int (*sv_fetch_syscall_args)(struct thread *, struct syscall_args *); const char **sv_syscallnames; + vm_offset_t sv_shared_page_base; + vm_offset_t sv_shared_page_len; + vm_offset_t sv_sigcode_base; + void *sv_shared_page_obj; }; #define SV_ILP32 0x000100 #define SV_LP64 0x000200 #define SV_IA32 0x004000 #define SV_AOUT 0x008000 +#define SV_SHP 0x010000 #define SV_ABI_MASK 0xff #define SV_CURPROC_FLAG(x) (curproc->p_sysent->sv_flags & (x)) @@ -222,6 +227,10 @@ int lkmressys(struct thread *, struct nosys_args *); int syscall_thread_enter(struct thread *td, struct sysent *se); void syscall_thread_exit(struct thread *td, struct sysent *se); +struct vm_object; +extern struct vm_object *shared_page_obj; +int shared_page_fill(int size, int align, const char *data); + #endif /* _KERNEL */ #endif /* !_SYS_SYSENT_H_ */