1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-22 00:35:15 +00:00

- bsd-user: Follow exec_copyout_strings more closely when setting

up guest stack. [1]
- Bump PORTREVISION.

Submitted by:	kan [1]
Obtained from:	21927cffcc [1]
This commit is contained in:
Juergen Lock 2014-07-06 18:14:57 +00:00
parent dd30e46f3a
commit c47e201eb2
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=360950
2 changed files with 276 additions and 1 deletions

View File

@ -3,7 +3,7 @@
PORTNAME= qemu
PORTVERSION= 2.0.0
PORTREVISION= 8
PORTREVISION= 9
CATEGORIES= emulators
MASTER_SITES= http://wiki.qemu.org/download/:release \
LOCAL/nox:snapshot
@ -76,6 +76,7 @@ EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-target_os_stack.h
EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-arm-target_arch_thread.h
EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-sparc64-target_arch_cpu.h
EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-trapsig
EXTRA_PATCHES+= ${FILESDIR}/extra-patch-21927cffcc7bcacbb953155f778200846df9f60e
.endif
CONFIGURE_ARGS+= --extra-ldflags=-L${LOCALBASE}/lib

View File

@ -0,0 +1,274 @@
From 96cc385829084403d39ad71d4ee366993900e632 Mon Sep 17 00:00:00 2001
From: Alexander Kabaev <kan@FreeBSD.ORG>
Date: Fri, 27 Jun 2014 16:42:16 -0400
Subject: [PATCH] Follow exec_copyout_strings more closely when setting up
guest stack.
Remove mysterious TARGET_SPACE_USRSPACE define that limited the
compined size of argvp and envp vectors to just 4k and use the same
calculation that FreeBSD kernel uses to allocate the space for
strings and vectors sans aux vector, which we do not support just
yet. Remove assumption that argv and env strings end up at the top
of the stack and pass the pointer around instead.
This allows one to run programs with more than 4096/sizeof(abi_long)
env and args strings on command line.
---
bsd-user/elfload.c | 11 +++++------
bsd-user/freebsd/target_os_elf.h | 3 ++-
bsd-user/freebsd/target_os_stack.h | 25 ++++++++++++++++---------
bsd-user/freebsd/target_os_vmparam.h | 1 -
bsd-user/netbsd/target_os_elf.h | 3 ++-
bsd-user/netbsd/target_os_stack.h | 6 +++++-
bsd-user/openbsd/target_os_elf.h | 3 ++-
bsd-user/openbsd/target_os_stack.h | 6 +++++-
bsd-user/qemu.h | 1 +
9 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 945e2a0..406d1c2 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -166,8 +166,8 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
return p;
}
-static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
- struct image_info *info)
+static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info,
+ abi_ulong *stackp, abi_ulong *stringp)
{
abi_ulong stack_base, size;
abi_long addr;
@@ -189,12 +189,10 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
target_stksiz = size;
target_stkbas = addr;
- if (setup_initial_stack(bprm, &p) != 0) {
+ if (setup_initial_stack(bprm, stackp, stringp) != 0) {
perror("stk setup");
exit(-1);
}
-
- return p;
}
static void set_brk(abi_ulong start, abi_ulong end)
@@ -819,7 +817,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
info->rss = 0;
- bprm->p = setup_arg_pages(bprm->p, bprm, info);
+ setup_arg_pages(bprm, info, &bprm->p, &bprm->stringp);
info->start_stack = bprm->p;
/* Now we do a little grungy work by mmaping the ELF image into
@@ -945,6 +943,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
bprm->p = target_create_elf_tables(bprm->p,
bprm->argc,
bprm->envc,
+ bprm->stringp,
&elf_ex,
load_addr, load_bias,
interp_load_addr,
diff --git a/bsd-user/freebsd/target_os_elf.h b/bsd-user/freebsd/target_os_elf.h
index 5bc689a..592a1c2 100644
--- a/bsd-user/freebsd/target_os_elf.h
+++ b/bsd-user/freebsd/target_os_elf.h
@@ -85,6 +85,7 @@ struct exec
#define DLINFO_ITEMS 12
static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
+ abi_ulong stringp,
struct elfhdr * exec,
abi_ulong load_addr,
abi_ulong load_bias,
@@ -140,7 +141,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
#endif
#undef NEW_AUX_ENT
- sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs);
return sp;
}
diff --git a/bsd-user/freebsd/target_os_stack.h b/bsd-user/freebsd/target_os_stack.h
index 73aea8f..410b282 100644
--- a/bsd-user/freebsd/target_os_stack.h
+++ b/bsd-user/freebsd/target_os_stack.h
@@ -44,7 +44,7 @@
* "destp" -> argv, env strings (up to 262144 bytes)
*/
static inline int setup_initial_stack(struct bsd_binprm *bprm,
- abi_ulong *ret_addr)
+ abi_ulong *ret_addr, abi_ulong *stringp)
{
int i;
abi_ulong stack_hi_addr;
@@ -88,6 +88,15 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm,
errno = EFAULT;
return -1;
}
+ /*
+ * Deviate from FreeBSD stack layout: force stack to new page here
+ * so that signal trampoline is not sharing the page with user stack
+ * frames. This is actively harmful in qemu as it marks pages with
+ * code it translated as read-only, which is somewhat problematic
+ * for user trying to use the stack as intended.
+ */
+ p = rounddown(p, TARGET_PAGE_SIZE);
+
/* Calculate the string space needed */
stringspace = 0;
for (i = 0; i < bprm->argc; ++i) {
@@ -100,20 +109,17 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm,
errno = ENOMEM;
return -1;
}
-
/* Make room for the argv and envp strings */
- argvp = roundup(p - TARGET_SPACE_USRSPACE - (TARGET_ARG_MAX - stringspace),
- sizeof(abi_ulong));
- p = destp = p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX;
-
+ destp = rounddown(p - stringspace, sizeof(abi_ulong));
+ p = argvp = destp - (bprm->argc + bprm->envc + 2) * sizeof(abi_ulong);
+ /* Remember the strings pointer */
+ if (stringp)
+ *stringp = destp;
/*
* Add argv strings. Note that the argv[] vectors are added by
* loader_build_argptr()
*/
/* XXX need to make room for auxargs */
- /* argvp = destp - ((bprm->argc + bprm->envc + 2) * sizeof(abi_ulong)); */
- /* envp = argvp + (bprm->argc + 2) * sizeof(abi_ulong); */
- envp = argvp + (bprm->argc + 1) * sizeof(abi_ulong);
ps_strs.ps_argvstr = tswapl(argvp);
ps_strs.ps_nargvstr = tswap32(bprm->argc);
for (i = 0; i < bprm->argc; ++i) {
@@ -138,6 +144,7 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm,
* Add env strings. Note that the envp[] vectors are added by
* loader_build_argptr().
*/
+ envp = argvp + sizeof(abi_ulong);
ps_strs.ps_envstr = tswapl(envp);
ps_strs.ps_nenvstr = tswap32(bprm->envc);
for (i = 0; i < bprm->envc; ++i) {
diff --git a/bsd-user/freebsd/target_os_vmparam.h b/bsd-user/freebsd/target_os_vmparam.h
index 80ac6c8..7415809 100644
--- a/bsd-user/freebsd/target_os_vmparam.h
+++ b/bsd-user/freebsd/target_os_vmparam.h
@@ -3,7 +3,6 @@
#include "target_arch_vmparam.h"
-#define TARGET_SPACE_USRSPACE 4096
#define TARGET_ARG_MAX 262144
/* Compare to sys/exec.h */
diff --git a/bsd-user/netbsd/target_os_elf.h b/bsd-user/netbsd/target_os_elf.h
index bf663d2..1f6421c 100644
--- a/bsd-user/netbsd/target_os_elf.h
+++ b/bsd-user/netbsd/target_os_elf.h
@@ -146,6 +146,7 @@ struct exec
#define DLINFO_ITEMS 12
static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
+ abi_ulong stringp,
struct elfhdr * exec,
abi_ulong load_addr,
abi_ulong load_bias,
@@ -219,7 +220,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
#endif
#undef NEW_AUX_ENT
- sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs);
return sp;
}
diff --git a/bsd-user/netbsd/target_os_stack.h b/bsd-user/netbsd/target_os_stack.h
index 1a26c3f..912207c 100644
--- a/bsd-user/netbsd/target_os_stack.h
+++ b/bsd-user/netbsd/target_os_stack.h
@@ -3,7 +3,8 @@
#include "target_arch_sigtramp.h"
-static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p,
+ abi_ulong *stringp)
{
int i;
abi_ulong stack_base;
@@ -13,6 +14,9 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
if (p) {
*p = stack_base;
}
+ if (stringp) {
+ *stringp = stack_base;
+ }
for (i = 0; i < MAX_ARG_PAGES; i++) {
if (bprm->page[i]) {
diff --git a/bsd-user/openbsd/target_os_elf.h b/bsd-user/openbsd/target_os_elf.h
index 978d944..b991e02 100644
--- a/bsd-user/openbsd/target_os_elf.h
+++ b/bsd-user/openbsd/target_os_elf.h
@@ -146,6 +146,7 @@ struct exec
#define DLINFO_ITEMS 12
static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
+ abi_ulong stringp,
struct elfhdr * exec,
abi_ulong load_addr,
abi_ulong load_bias,
@@ -219,7 +220,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
#endif
#undef NEW_AUX_ENT
- sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs);
return sp;
}
diff --git a/bsd-user/openbsd/target_os_stack.h b/bsd-user/openbsd/target_os_stack.h
index 1a26c3f..42959fd 100644
--- a/bsd-user/openbsd/target_os_stack.h
+++ b/bsd-user/openbsd/target_os_stack.h
@@ -3,7 +3,8 @@
#include "target_arch_sigtramp.h"
-static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p,
+ abi_ulong *stringp)
{
int i;
abi_ulong stack_base;
@@ -13,6 +14,9 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
if (p) {
*p = stack_base;
}
+ if (stringp) {
+ *stringp = stack_base;
+ }
for (i = 0; i < MAX_ARG_PAGES; i++) {
if (bprm->page[i]) {
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5791037..09af1b4 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -134,6 +134,7 @@ struct bsd_binprm {
char buf[128];
void *page[MAX_ARG_PAGES];
abi_ulong p;
+ abi_ulong stringp;
int fd;
int e_uid, e_gid;
int argc, envc;
--
1.9.3