]> git.pld-linux.org Git - packages/qemu.git/blobdiff - qemu-user-execve.patch
- fixed -system-tricore description
[packages/qemu.git] / qemu-user-execve.patch
index 6f89ff37e44ae7b879980804f684e5e7efabd321..8a0cf71c293893ab1f9d95c3f93fdfe577e3725f 100644 (file)
@@ -1,10 +1,28 @@
+Discussion:
 https://resin.io/blog/building-arm-containers-on-any-x86-machine-even-dockerhub/
+
 https://github.com/resin-io/qemu/commit/782e5bb77014ff136f7bb6133a911e5f53e914a7
 
-From 782e5bb77014ff136f7bb6133a911e5f53e914a7 Mon Sep 17 00:00:00 2001
+https://github.com/resin-io/qemu/commit/782e5bb77014ff136f7bb6133a911e5f53e914a7#commitcomment-17193923
+It has gone through review[1][2][3] and I'm waiting for the maintainer of the linux-user subsystem to accept it in his tree.
+
+[1] https://patchwork.ozlabs.org/patch/569452/
+[2] https://patchwork.ozlabs.org/patch/573877/
+[3] https://patchwork.ozlabs.org/patch/582756/
+
+From patchwork Mon Feb 15 05:51:47 2016
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3] linux-user: add option to intercept execve() syscalls
 From: Petros Angelatos <petrosagg@resin.io>
-Date: Thu, 24 Dec 2015 14:43:17 -0800
-Subject: [PATCH] linux-user: add option to intercept execve() syscalls
+X-Patchwork-Id: 582756
+Message-Id: <1455515507-26877-1-git-send-email-petrosagg@resin.io>
+To: qemu-devel@nongnu.org
+Cc: lucas.kaldstrom@hotmail.co.uk, peter.maydell@linaro.org,
+ riku.voipio@iki.fi, 
+ laurent@vivier.eu, Petros Angelatos <petrosagg@resin.io>
+Date: Sun, 14 Feb 2016 21:51:47 -0800
 
 In order for one to use QEMU user mode emulation under a chroot, it is
 required to use binfmt_misc. This can be avoided by QEMU never doing a
@@ -21,25 +39,17 @@ the kernel will try to run the interpreter of a script without QEMU and
 get an invalid exec format error.
 
 Signed-off-by: Petros Angelatos <petrosagg@resin.io>
+Tested-by: Laurent Vivier <laurent@vivier.eu>
+Reviewed-by: Laurent Vivier <laurent@vivier.eu>
 ---
- linux-user/main.c    |  36 ++++++++++++++++
- linux-user/qemu.h    |   1 +
- linux-user/syscall.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 3 files changed, 153 insertions(+), 1 deletion(-)
+v3 changes:
+       - rebase the patchset against current code
 
 diff --git a/linux-user/main.c b/linux-user/main.c
-index 700724e..16cce85 100644
+index ee12035..5951279 100644
 --- a/linux-user/main.c
 +++ b/linux-user/main.c
-@@ -17,6 +17,7 @@
-  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
-  */
- #include "qemu/osdep.h"
-+#include <sys/auxv.h>
- #include <sys/mman.h>
- #include <sys/syscall.h>
- #include <sys/resource.h>
-@@ -75,6 +76,7 @@ static void usage(int exitcode);
+@@ -79,6 +79,7 @@ static void usage(int exitcode);
  
  static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
  const char *qemu_uname_release;
@@ -47,59 +57,32 @@ index 700724e..16cce85 100644
  
  /* 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)
-     have_guest_base = 1;
+@@ -3828,6 +3829,11 @@ static void handle_arg_guest_base(const char *arg)
+     have_guest_base = true;
  }
  
 +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,
 diff --git a/linux-user/qemu.h b/linux-user/qemu.h
-index 26b0ba2..8270268 100644
+index bd90cc3..0d9b058 100644
 --- a/linux-user/qemu.h
 +++ b/linux-user/qemu.h
-@@ -137,6 +137,7 @@ void init_task_state(TaskState *ts);
+@@ -140,6 +140,7 @@ void init_task_state(TaskState *ts);
  void task_settid(TaskState *);
  void stop_all_tasks(void);
  extern const char *qemu_uname_release;
@@ -107,22 +90,14 @@ index 26b0ba2..8270268 100644
  extern unsigned long mmap_min_addr;
  
  /* ??? See if we can avoid exposing so much of the loader internals.  */
-diff --git a/linux-user/syscall.c b/linux-user/syscall.c
-index 9517531..66446f7 100644
---- a/linux-user/syscall.c
-+++ b/linux-user/syscall.c
-@@ -99,6 +99,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
- #include <linux/route.h>
- #include <linux/filter.h>
- #include <linux/blkpg.h>
-+#include <linux/binfmts.h>
- #include "linux_loop.h"
- #include "uname.h"
-@@ -5845,6 +5846,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[])
@@ -133,30 +108,19 @@ index 9517531..66446f7 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);
@@ -173,7 +137,7 @@ index 9517531..66446f7 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) {
@@ -184,7 +148,7 @@ index 9517531..66446f7 100644
 +                break;
 +            }
 +        }
-+        for (cp = buf + 2; (*cp == ' ') || (*cp == '\t'); cp++) {
++        for (cp = buf+2; (*cp == ' ') || (*cp == '\t'); cp++) {
 +            /* nothing */ ;
 +        }
 +        if (*cp == '\0') {
@@ -232,19 +196,22 @@ index 9517531..66446f7 100644
 +        new_argp[2] = argv[0];
 +    }
 +
-+    return get_errno(execve(qemu_execve_path, new_argp, envp));
++    return get_errno(safe_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>. */
-@@ -6104,7 +6217,9 @@ 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));
-+
-+            ret = qemu_execve(p, argp, envp);
+ static int target_to_host_cpu_mask(unsigned long *host_mask,
+                                    size_t host_size,
+                                    abi_ulong target_addr,
+@@ -8257,7 +8257,12 @@
+              * before the execve completes and makes it the other
+              * program's problem.
+              */
+-            ret = get_errno(safe_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);
  
This page took 0.035545 seconds and 4 git commands to generate.