-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
update patches loading to support v6.1.0 and cpu-max
Signed-off-by: Tonis Tiigi <[email protected]>
- Loading branch information
1 parent
99c76af
commit fb32164
Showing
13 changed files
with
1,143 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
...ildkit-direct-execve-v6.0/0001-linux-user-have-execve-call-qemu-via-proc-self-exe-t.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
From dc472d34ed686cba2804f254e3d803904791eaf6 Mon Sep 17 00:00:00 2001 | ||
From: Tibor Vass <[email protected]> | ||
Date: Mon, 1 Jun 2020 23:08:25 +0000 | ||
Subject: [PATCH 1/5] linux-user: have execve call qemu via /proc/self/exe to | ||
not rely on binfmt_misc | ||
|
||
It is assumed that when a guest program calls execve syscall it wants to | ||
execute a program on the same guest architecture and not the host architecture. | ||
|
||
Previously, such a guest program would have execve syscall error out with: | ||
"exec format error". | ||
|
||
A common solution is to register the qemu binary in binfmt_misc but that is not a | ||
userland-friendly solution, requiring to modify kernel state. | ||
|
||
This patch injects /proc/self/exe as the first parameter and the qemu program name | ||
as argv[0] to execve. | ||
|
||
Signed-off-by: Tibor Vass <[email protected]> | ||
(cherry picked from commit bc8e2fdae6cd4f9ff1d487056ca3bc598a3187bc) | ||
Signed-off-by: Tibor Vass <[email protected]> | ||
--- | ||
linux-user/syscall.c | 35 ++++++++++++++++++++++++++++++----- | ||
1 file changed, 30 insertions(+), 5 deletions(-) | ||
|
||
diff --git a/linux-user/syscall.c b/linux-user/syscall.c | ||
index 95d79ddc43..409686fdca 100644 | ||
--- a/linux-user/syscall.c | ||
+++ b/linux-user/syscall.c | ||
@@ -8498,10 +8498,37 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, | ||
envc++; | ||
} | ||
|
||
- argp = g_new0(char *, argc + 1); | ||
+ argp = g_new0(char *, argc + 4); | ||
envp = g_new0(char *, envc + 1); | ||
|
||
- for (gp = guest_argp, q = argp; gp; | ||
+ if (!(p = lock_user_string(arg1))) | ||
+ goto execve_efault; | ||
+ | ||
+ /* if pathname is /proc/self/exe then retrieve the path passed to qemu via command line */ | ||
+ if (is_proc_myself(p, "exe")) { | ||
+ CPUState *cpu = env_cpu((CPUArchState *)cpu_env); | ||
+ TaskState *ts = cpu->opaque; | ||
+ p = ts->bprm->filename; | ||
+ } | ||
+ | ||
+ /* retrieve guest argv0 */ | ||
+ if (get_user_ual(addr, guest_argp)) | ||
+ goto execve_efault; | ||
+ | ||
+ /* | ||
+ * From the guest, the call | ||
+ * execve(pathname, [argv0, argv1], envp) | ||
+ * on the host, becomes: | ||
+ * execve("/proc/self/exe", [qemu_progname, "-0", argv0, pathname, argv1], envp) | ||
+ * where qemu_progname is the error message prefix for qemu | ||
+ */ | ||
+ argp[0] = (char*)error_get_progname(); | ||
+ argp[1] = (char*)"-0"; | ||
+ argp[2] = (char*)lock_user_string(addr); | ||
+ argp[3] = p; | ||
+ | ||
+ /* copy guest argv1 onwards to host argv4 onwards */ | ||
+ for (gp = guest_argp + 1*sizeof(abi_ulong), q = argp + 4; gp; | ||
gp += sizeof(abi_ulong), q++) { | ||
if (get_user_ual(addr, gp)) | ||
goto execve_efault; | ||
@@ -8525,8 +8552,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, | ||
} | ||
*q = NULL; | ||
|
||
- if (!(p = lock_user_string(arg1))) | ||
- goto execve_efault; | ||
/* Although execve() is not an interruptible syscall it is | ||
* a special case where we must use the safe_syscall wrapper: | ||
* if we allow a signal to happen before we make the host | ||
@@ -8537,7 +8562,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, | ||
* before the execve completes and makes it the other | ||
* program's problem. | ||
*/ | ||
- ret = get_errno(safe_execve(p, argp, envp)); | ||
+ ret = get_errno(safe_execve("/proc/self/exe", argp, envp)); | ||
unlock_user(p, arg1, 0); | ||
|
||
goto execve_end; | ||
-- | ||
2.29.2 | ||
|
78 changes: 78 additions & 0 deletions
78
patches/buildkit-direct-execve-v6.0/0002-linux-user-lookup-user-program-in-PATH.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
From 945c7a9e623d915c2e1535894aa90362ed114c08 Mon Sep 17 00:00:00 2001 | ||
From: Tibor Vass <[email protected]> | ||
Date: Tue, 2 Jun 2020 10:39:48 +0000 | ||
Subject: [PATCH 2/5] linux-user: lookup user program in PATH | ||
|
||
Signed-off-by: Tibor Vass <[email protected]> | ||
(cherry picked from commit 1102f3dc7a4db75e72d25b2eab8503f52c44a542) | ||
Signed-off-by: Tibor Vass <[email protected]> | ||
--- | ||
linux-user/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 44 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/linux-user/main.c b/linux-user/main.c | ||
index f956afccab..36f0c85957 100644 | ||
--- a/linux-user/main.c | ||
+++ b/linux-user/main.c | ||
@@ -551,6 +551,45 @@ static void usage(int exitcode) | ||
exit(exitcode); | ||
} | ||
|
||
+/* | ||
+ * path_lookup searches for an executable filename in the directories named by the PATH environment variable. | ||
+ * Returns a copy of filename if it is an absolute path or could not find a match. | ||
+ * Caller is responsible to free returned string. | ||
+ * Adapted from musl's execvp implementation. | ||
+ */ | ||
+static char *path_lookup(char *filename) { | ||
+ const char *p, *z, *path = getenv("PATH"); | ||
+ size_t l, k; | ||
+ struct stat buf; | ||
+ | ||
+ /* if PATH is not set or filename is absolute path return filename */ | ||
+ if (!path || !filename || filename[0] == '/') | ||
+ return strndup(filename, NAME_MAX+1); | ||
+ | ||
+ k = strnlen(filename, NAME_MAX+1); | ||
+ if (k > NAME_MAX) { | ||
+ errno = ENAMETOOLONG; | ||
+ return NULL; | ||
+ } | ||
+ l = strnlen(path, PATH_MAX-1)+1; | ||
+ | ||
+ for (p = path; ; p = z) { | ||
+ char *b = calloc(l+k+1, sizeof(char)); | ||
+ z = strchrnul(p, ':'); | ||
+ if (z-p >= l) { | ||
+ if (!*z++) break; | ||
+ continue; | ||
+ } | ||
+ memcpy(b, p, z-p); | ||
+ b[z-p] = '/'; | ||
+ memcpy(b+(z-p)+(z>p), filename, k+1); | ||
+ if (!stat(b, &buf) && !(buf.st_mode & S_IFDIR) && (buf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) | ||
+ return b; | ||
+ if (!*z++) break; | ||
+ } | ||
+ return strndup(filename, NAME_MAX+1); | ||
+} | ||
+ | ||
static int parse_args(int argc, char **argv) | ||
{ | ||
const char *r; | ||
@@ -616,7 +655,11 @@ static int parse_args(int argc, char **argv) | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
- exec_path = argv[optind]; | ||
+ /* not freeing exec_path as it is needed for the lifetime of the process */ | ||
+ if (!(exec_path = path_lookup(argv[optind]))) { | ||
+ (void) fprintf(stderr, "qemu: could not find user program %s: %s\n", exec_path, strerror(errno)); | ||
+ exit(EXIT_FAILURE); | ||
+ } | ||
|
||
return optind; | ||
} | ||
-- | ||
2.29.2 | ||
|
Oops, something went wrong.