summaryrefslogtreecommitdiffstats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorTimothy E Baldwin2016-05-12 19:47:50 +0200
committerRiku Voipio2016-05-27 13:50:38 +0200
commitffdcbe223d23461669869e85786145cce65e1e8c (patch)
tree67fa1fb1e1c3a553b2206cbab5be761a0ac86204 /linux-user/syscall.c
parentlinux-user: Use safe_syscall for wait system calls (diff)
downloadqemu-ffdcbe223d23461669869e85786145cce65e1e8c.tar.gz
qemu-ffdcbe223d23461669869e85786145cce65e1e8c.tar.xz
qemu-ffdcbe223d23461669869e85786145cce65e1e8c.zip
linux-user: Use safe_syscall for execve syscall
Wrap execve() in the safe-syscall handling. Although execve() is not an interruptible syscall, it is a special case: if we allow a signal to happen before we make the host$ syscall then we will 'lose' it, because at the point of execve the process leaves QEMU's control. So we use the safe syscall wrapper to ensure that we either take the signal as a guest signal, or else it does not happen before the execve completes and makes it the other program's problem. The practical upshot is that without this SIGTERM could fail to terminate the process. Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk> Message-id: 1441497448-32489-25-git-send-email-T.E.Baldwin99@members.leeds.ac.uk [PMM: expanded commit message to explain in more detail why this is needed, and add comment about it too] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d9f4695624..dea827fe04 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -703,6 +703,7 @@ safe_syscall4(pid_t, wait4, pid_t, pid, int *, status, int, options, \
struct rusage *, rusage)
safe_syscall5(int, waitid, idtype_t, idtype, id_t, id, siginfo_t *, infop, \
int, options, struct rusage *, rusage)
+safe_syscall3(int, execve, const char *, filename, char **, argv, char **, envp)
static inline int host_to_target_sock_type(int host_type)
{
@@ -6179,7 +6180,17 @@ 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));
+ /* 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
+ * syscall then we will 'lose' it, because at the point of
+ * execve the process leaves QEMU's control. So we use the
+ * safe syscall wrapper to ensure that we either take the
+ * signal as a guest signal, or else it does not happen
+ * before the execve completes and makes it the other
+ * program's problem.
+ */
+ ret = get_errno(safe_execve(p, argp, envp));
unlock_user(p, arg1, 0);
goto execve_end;