-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When the execvp syscall is invoked, the system PATH should be searched for the executable to invoke, with the first match in the PATH being invoked. However, the call being modified to inject qemu breaks this behaviour, as it's not till _after_ qemu is invoked that the presence or executability is checked, which is too late. ENOENT and EACCESS aren't returned from the execve call, which stops execvp looping over the PATH and aborts the entire process. This is resolved by testing the target command prior to executing it via qemu, returning the appropriate error codes. In the case of relative paths, the prepending of the workdir resulted in a corrupted string being returned such as `��@/work/./script.sh`. This is because with malloc the memory isn't zeroed, so the memory is 'dirty'. As a result, the strncat doesn't insert the workdir at the start as desired, and an invalid path is returned. Testing the affected calls is tricky, because cross-arch binaries for 'env' and other commands are needed in the container, and need to be run via emulation, which then `execvp`/`execve` out to other things which must also be for that architecture, and run via the emulator. Including a static busybox binary for the cross-arch, and customising the PATH for emulated calls to prefer those gives the desired behaviour. Signed-off-by: David Ackroyd <dackroyd@nine.com.au>
- Loading branch information
Showing
7 changed files
with
147 additions
and
6 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
50 changes: 50 additions & 0 deletions
50
patches/buildkit-direct-execve-v7.1/0007-fix-execvp-PATH-handling.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,50 @@ | ||
From 511efc9c787b9d6ea00cc2c1f6a6ec781ca7bb0c Mon Sep 17 00:00:00 2001 | ||
From: David Ackroyd <dackroyd@nine.com.au> | ||
Date: Tue, 22 Nov 2022 11:18:58 +1100 | ||
Subject: [PATCH] fix execvp PATH handling | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
When the execvp syscall is invoked, the system PATH should be searched | ||
for the executable to invoke, with the first match in the PATH being | ||
invoked. However, the call being modified to inject qemu breaks this | ||
behaviour, as it's not till _after_ qemu is invoked that the presence or | ||
executability is checked, which is too late. ENOENT and EACCESS aren't | ||
returned from the execve call, which stops execvp looping over the PATH | ||
and aborts the entire process. | ||
|
||
This is resolved by testing the target command prior to executing it via | ||
qemu, returning the appropriate error codes. | ||
|
||
Signed-off-by: David Ackroyd <dackroyd@nine.com.au> | ||
--- | ||
linux-user/syscall.c | 15 +++++++++++++++ | ||
1 file changed, 15 insertions(+) | ||
|
||
diff --git a/linux-user/syscall.c b/linux-user/syscall.c | ||
index b3d913c851..213e17a4b8 100644 | ||
--- a/linux-user/syscall.c | ||
+++ b/linux-user/syscall.c | ||
@@ -8840,6 +8840,21 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, | ||
goto execve_end; | ||
} | ||
|
||
+ /* | ||
+ * Check whether executable up front, as running once the qemu process is started these failures | ||
+ * will happen internally there, and only exposed as a non-zero exit code for qemu. | ||
+ */ | ||
+ ret = get_errno(stat(argp[3], &st)); | ||
+ if (is_error(ret)) { | ||
+ ret = -host_to_target_errno(errno); | ||
+ goto execve_end; | ||
+ } | ||
+ | ||
+ if ((st.st_mode & S_IFDIR) || !(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) { | ||
+ ret = TARGET_EACCES; | ||
+ goto execve_end; | ||
+ } | ||
+ | ||
/* 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++) { |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#!/work/env ./printargs |
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,3 @@ | ||
#!/work/env sh | ||
|
||
./printargs "$@" |
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