* [Qemu-devel] [PATCH,APPLIED] Usermode exec-stack fix
@ 2010-06-16 12:10 Paul Brook
0 siblings, 0 replies; only message in thread
From: Paul Brook @ 2010-06-16 12:10 UTC (permalink / raw)
To: qemu-devel
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 <paul@codesourcery.com>
---
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(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 2d920f2..accb44d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -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;
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 914de1f..8ad130a 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -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;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index dab3597..1878d5a 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -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;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e94f1ee..0ebe7e1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -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
--
1.7.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2010-06-16 12:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-16 12:10 [Qemu-devel] [PATCH,APPLIED] Usermode exec-stack fix Paul Brook
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.