X-Git-Url: https://git.tld-linux.org/?p=packages%2Fqemu.git;a=blobdiff_plain;f=qemu-user-execve.patch;h=e567b84438bb664827b49db511b72a216b4d72e0;hp=78c0e57e89af77d79623055e370778f720dca8a1;hb=790b7a021ab1b934ac5b1977cdd59d223c748d78;hpb=0652bf3563918ba890a7eb4a6c20bd7d78938832 diff --git a/qemu-user-execve.patch b/qemu-user-execve.patch index 78c0e57..e567b84 100644 --- a/qemu-user-execve.patch +++ b/qemu-user-execve.patch @@ -1,4 +1,6 @@ +Discussion: https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/ + https://github.com/resin-io/qemu/commit/782e5bb77014ff136f7bb6133a911e5f53e914a7 https://github.com/resin-io/qemu/commit/782e5bb77014ff136f7bb6133a911e5f53e914a7#commitcomment-17193923 @@ -43,17 +45,11 @@ Reviewed-by: Laurent Vivier v3 changes: - rebase the patchset against current code ---- qemu-2.7.0/linux-user/main.c~ 2016-09-26 12:07:20.000000000 +0300 -+++ qemu-2.7.0/linux-user/main.c 2016-09-26 12:09:24.258470304 +0300 -@@ -18,6 +18,7 @@ - */ - #include "qemu/osdep.h" - #include "qemu-version.h" -+#include - #include - #include - -@@ -75,6 +76,7 @@ static void usage(int exitcode); +diff --git a/linux-user/main.c b/linux-user/main.c +index ee12035..5951279 100644 +--- a/linux-user/main.c ++++ b/linux-user/main.c +@@ -79,6 +79,7 @@ static void usage(int exitcode); static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; const char *qemu_uname_release; @@ -61,51 +57,24 @@ v3 changes: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so we allocate a bigger stack. Need a better solution, for example -@@ -3824,6 +3826,38 @@ static void handle_arg_guest_base(const char *arg) +@@ -3828,6 +3829,11 @@ static void handle_arg_guest_base(const char *arg) have_guest_base = 1; } +static void handle_arg_execve(const char *arg) +{ -+ const char *execfn; -+ char buf[PATH_MAX]; -+ char *ret; -+ int len; -+ -+ /* try getauxval() */ -+ execfn = (const char *) getauxval(AT_EXECFN); -+ -+ if (execfn != 0) { -+ ret = realpath(execfn, buf); -+ -+ if (ret != NULL) { -+ qemu_execve_path = strdup(buf); -+ return; -+ } -+ } -+ -+ /* try /proc/self/exe */ -+ len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); -+ -+ if (len != -1) { -+ buf[len] = '\0'; -+ qemu_execve_path = strdup(buf); -+ return; -+ } -+ -+ fprintf(stderr, "qemu_execve: unable to determine intepreter's path\n"); -+ exit(EXIT_FAILURE); ++ qemu_execve_path = strdup(arg); +} + static void handle_arg_reserved_va(const char *arg) { char *p; -@@ -3909,6 +3943,8 @@ static const struct qemu_argument arg_table[] = { +@@ -3913,6 +3919,8 @@ static const struct qemu_argument arg_table[] = { "uname", "set qemu uname release string to 'uname'"}, {"B", "QEMU_GUEST_BASE", true, handle_arg_guest_base, "address", "set guest_base address to 'address'"}, -+ {"execve", "QEMU_EXECVE", false, handle_arg_execve, -+ "", "use this interpreter when a process calls execve()"}, ++ {"execve", "QEMU_EXECVE", true, handle_arg_execve, ++ "path", "use interpreter at 'path' when a process calls execve()"}, {"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va, "size", "reserve 'size' bytes for guest virtual address space"}, {"d", "QEMU_LOG", true, handle_arg_log, @@ -121,20 +90,14 @@ index bd90cc3..0d9b058 100644 extern unsigned long mmap_min_addr; /* ??? See if we can avoid exposing so much of the loader internals. */ ---- qemu-2.7.0/linux-user/syscall.c~ 2016-09-26 12:10:36.000000000 +0300 -+++ qemu-2.7.0/linux-user/syscall.c 2016-09-26 12:13:54.312490312 +0300 -@@ -99,6 +99,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -5842,6 +5843,118 @@ static target_timer_t get_timer_id(abi_long arg) +--- qemu-2.12.0/linux-user/syscall.c~ 2018-04-30 21:43:39.000000000 +0300 ++++ qemu-2.12.0/linux-user/syscall.c 2018-04-30 21:46:36.362935706 +0300 +@@ -5854,6 +5854,109 @@ static target_timer_t get_timer_id(abi_long arg) return timerid; } ++#define BINPRM_BUF_SIZE 128 ++ +/* qemu_execve() Must return target values and target errnos. */ +static abi_long qemu_execve(char *filename, char *argv[], + char *envp[]) @@ -145,30 +108,19 @@ index bd90cc3..0d9b058 100644 + char *cp; + char buf[BINPRM_BUF_SIZE]; + -+ /* normal execve case */ -+ if (qemu_execve_path == NULL || *qemu_execve_path == 0) { -+ return get_errno(execve(filename, argv, envp)); -+ } -+ + for (argc = 0; argv[argc] != NULL; argc++) { + /* nothing */ ; + } + + fd = open(filename, O_RDONLY); + if (fd == -1) { -+ return get_errno(fd); ++ return -ENOENT; + } + + ret = read(fd, buf, BINPRM_BUF_SIZE); + if (ret == -1) { + close(fd); -+ return get_errno(ret); -+ } -+ -+ /* if we have less than 2 bytes, we can guess it is not executable */ -+ if (ret < 2) { -+ close(fd); -+ return -host_to_target_errno(ENOEXEC); ++ return -ENOENT; + } + + close(fd); @@ -185,7 +137,7 @@ index bd90cc3..0d9b058 100644 + buf[BINPRM_BUF_SIZE - 1] = '\0'; + cp = strchr(buf, '\n'); + if (cp == NULL) { -+ cp = buf + BINPRM_BUF_SIZE - 1; ++ cp = buf+BINPRM_BUF_SIZE-1; + } + *cp = '\0'; + while (cp > buf) { @@ -196,7 +148,7 @@ index bd90cc3..0d9b058 100644 + break; + } + } -+ for (cp = buf + 2; (*cp == ' ') || (*cp == '\t'); cp++) { ++ for (cp = buf+2; (*cp == ' ') || (*cp == '\t'); cp++) { + /* nothing */ ; + } + if (*cp == '\0') { @@ -250,12 +202,17 @@ index bd90cc3..0d9b058 100644 /* do_syscall() should always have a single exit point at the end so that actions, such as logging of syscall results, can be performed. All errnos that do_syscall() returns must be -TARGET_. */ -@@ -7703,7 +7703,7 @@ +@@ -8257,7 +8257,12 @@ * before the execve completes and makes it the other * program's problem. */ - ret = get_errno(safe_execve(p, argp, envp)); -+ ret = qemu_execve(p, argp, envp); ++ if (qemu_execve_path && *qemu_execve_path) { ++ ret = get_errno(qemu_execve(p, argp, envp)); ++ } else { ++ ret = get_errno(safe_execve(p, argp, envp)); ++ } ++ unlock_user(p, arg1, 0); goto execve_end;