]> git.pld-linux.org Git - packages/qemu.git/commitdiff
update qemu-user-execve.patch
authorElan Ruusamäe <glen@pld-linux.org>
Mon, 30 Apr 2018 18:44:00 +0000 (21:44 +0300)
committerElan Ruusamäe <glen@pld-linux.org>
Mon, 30 Apr 2018 18:44:00 +0000 (21:44 +0300)
updated from https://patchwork.kernel.org/patch/8052841/

qemu-user-execve.patch

index 78c0e57e89af77d79623055e370778f720dca8a1..48e802c425d0122c28291043bd614dd5f35016b2 100644 (file)
@@ -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 <laurent@vivier.eu>
 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 <sys/auxv.h>
- #include <sys/syscall.h>
- #include <sys/resource.h>
-@@ -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,16 @@ 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 <linux/reboot.h>
- #include <linux/route.h>
- #include <linux/filter.h>
-+#include <linux/binfmts.h>
- #include <linux/blkpg.h>
- #include <netpacket/packet.h>
- #include <linux/netlink.h>
-@@ -5842,6 +5843,118 @@ static target_timer_t get_timer_id(abi_long arg)
+diff --git a/linux-user/syscall.c b/linux-user/syscall.c
+index 0cbace4..d0b5442 100644
+--- a/linux-user/syscall.c
++++ b/linux-user/syscall.c
+@@ -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 +110,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 +139,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 +150,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') {
@@ -244,18 +198,24 @@ index bd90cc3..0d9b058 100644
 +        new_argp[2] = argv[0];
 +    }
 +
-+    return get_errno(safe_execve(qemu_execve_path, new_argp, envp));
++    return get_errno(execve(qemu_execve_path, new_argp, envp));
 +}
 +
  /* 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_<errcode>. */
-@@ -7703,7 +7703,7 @@
-              * 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);
+@@ -6113,7 +6216,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
+             if (!(p = lock_user_string(arg1)))
+                 goto execve_efault;
+-            ret = get_errno(execve(p, argp, envp));
++
++            if (qemu_execve_path && *qemu_execve_path) {
++                ret = get_errno(qemu_execve(p, argp, envp));
++            } else {
++                ret = get_errno(execve(p, argp, envp));
++            }
++
              unlock_user(p, arg1, 0);
  
              goto execve_end;
This page took 0.052453 seconds and 4 git commands to generate.