Permalink
Browse files

Merge pull request #6 from akabaev/bsd-user

Follow exec_copyout_strings more closely when setting up guest stack.

Thanks!  This seems to make mips much more happy.
  • Loading branch information...
2 parents 19d66fa + 96cc385 commit 21927cffcc7bcacbb953155f778200846df9f60e @seanbruno committed Jul 6, 2014
View
@@ -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,
@@ -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;
}
@@ -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) {
@@ -3,7 +3,6 @@
#include "target_arch_vmparam.h"
-#define TARGET_SPACE_USRSPACE 4096
#define TARGET_ARG_MAX 262144
/* Compare to sys/exec.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;
}
@@ -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]) {
@@ -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;
}
@@ -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]) {
View
@@ -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;

0 comments on commit 21927cf

Please sign in to comment.