summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormatthew <matthew@openbsd.org>2014-06-11 20:39:18 +0000
committermatthew <matthew@openbsd.org>2014-06-11 20:39:18 +0000
commit2ea18d853ded9e71461a266bd211991fef8aed9c (patch)
treef7dd776dfa1c1a1bc0fd08b674401c524e5e0967
parentReject negative file offsets in /dev/ksyms. (diff)
downloadwireguard-openbsd-2ea18d853ded9e71461a266bd211991fef8aed9c.tar.xz
wireguard-openbsd-2ea18d853ded9e71461a266bd211991fef8aed9c.zip
Fix wait4 to not modify status or rusage if we return 0 because of
WNOHANG, in accordance with POSIX. Additionally, if rusage is requested but the waited-on process did not terminate, return zero bytes instead of kernel stack garbage. ok deraadt, millert
-rw-r--r--sys/kern/kern_exit.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index b7326c63517..97d1a76b3f2 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.142 2014/05/15 04:43:25 guenther Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.143 2014/06/11 20:39:18 matthew Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -490,10 +490,10 @@ sys_wait4(struct proc *q, void *v, register_t *retval)
error = dowait4(q, SCARG(uap, pid),
SCARG(uap, status) ? &status : NULL,
SCARG(uap, options), SCARG(uap, rusage) ? &ru : NULL, retval);
- if (error == 0 && SCARG(uap, status)) {
+ if (error == 0 && retval[0] > 0 && SCARG(uap, status)) {
error = copyout(&status, SCARG(uap, status), sizeof(status));
}
- if (error == 0 && SCARG(uap, rusage)) {
+ if (error == 0 && retval[0] > 0 && SCARG(uap, rusage)) {
error = copyout(&ru, SCARG(uap, rusage), sizeof(ru));
#ifdef KTRACE
if (error == 0 && KTRPOINT(q, KTR_STRUCT))
@@ -549,6 +549,8 @@ loop:
if (statusp != NULL)
*statusp = W_STOPCODE(pr->ps_single->p_xstat);
+ if (rusage != NULL)
+ memset(rusage, 0, sizeof(*rusage));
return (0);
}
if (p->p_stat == SSTOP &&
@@ -561,6 +563,8 @@ loop:
if (statusp != NULL)
*statusp = W_STOPCODE(p->p_xstat);
+ if (rusage != NULL)
+ memset(rusage, 0, sizeof(*rusage));
return (0);
}
if ((options & WCONTINUED) && (p->p_flag & P_CONTINUED)) {
@@ -569,6 +573,8 @@ loop:
if (statusp != NULL)
*statusp = _WCONTINUED;
+ if (rusage != NULL)
+ memset(rusage, 0, sizeof(*rusage));
return (0);
}
}