Usermode exec-stack fix
PATCH 1/1 Usermode exec-stack fix
When loading a shared library that requires an executable stack, glibc uses the mprotext PROT_GROWSDOWN flag to achieve this. We don't support PROT_GROWSDOWN.
Add a special case to handle changing the stack permissions in this way.
Signed-off-by Paul Brook <[email protected]>
--- linux-user/elfload.c | 1 + linux-user/flatload.c | 1 + linux-user/qemu.h | 1 + linux-user/syscall.c | 11 +++++++++++ 4 files changed, 14 insertions(+), 0 deletions(-)
linux-user/elfload.c +1 -0
@@ -1018,6 +1018,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,/* we reserve one extra page at the top of the stack as guard */ target_mprotect (error + size, qemu_host_page_size,PROT_NONE ); + info->stack_limit = error; stack_base = error + size -MAX_ARG_PAGES *TARGET_PAGE_SIZE ; p += stack_base;
linux-user/flatload.c +1 -0
@@ -802,6 +802,7 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, info->end_data = libinfo[0 ].end_data; info->start_brk = libinfo[0 ].start_brk; info->start_stack = sp; + info->stack_limit = libinfo[0 ].start_brk; info->entry = start_addr; info->code_offset = info->start_code; info->data_offset = info->start_data - libinfo[0 ].text_len;
linux-user/qemu.h +1 -0
@@ -42,6 +42,7 @@ struct image_info {abi_ulong mmap;abi_ulong rss;abi_ulong start_stack; +abi_ulong stack_limit;abi_ulong entry;abi_ulong code_offset;abi_ulong data_offset;
linux-user/syscall.c +11 -0
@@ -5400,6 +5400,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret =get_errno (target_munmap (arg1, arg2));break ;case TARGET_NR_mprotect: + { +TaskState *ts = ((CPUState *)cpu_env)->opaque; +/* Special hack to detect libc making the stack executable. */ +if ((arg3 &PROT_GROWSDOWN ) + && arg1 >= ts->info->stack_limit + && arg1 <= ts->info->start_stack) { + arg3 &= ~PROT_GROWSDOWN ; + arg2 = arg2 + arg1 - ts->info->stack_limit; + arg1 = ts->info->stack_limit; + } + } ret =get_errno (target_mprotect (arg1, arg2, arg3));break ;#ifdef TARGET_NR_mremap
Signature · 1 line
1.7.1