summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2020-03-23 15:42:11 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2020-03-23 15:42:11 +0000
commit71f63dcb2a44ed48f5f764c229061a0de6d8a499 (patch)
tree729ba07ce2a6210621bd7f05760f3b77c8ef7f6d /sys
parent249d621757d2e1fe2169ff6529ee1851a1fd338a (diff)
Prevent tsleep(9) with PCATCH from returning immediately without error
when called during execve(2). This was a caused by initializing sls_sig with value 0 in r1.164 of kern_synch.c. Previously, tsleep(9) returned immediately with EINTR in similar circumstances. The immediate return without error can cause a system hang. For example, vwaitforio() could end up spinning if called during execve(2) because the thread did not enter sleep and other threads were not able to finish the I/O. tsleep vwaitforio nfs_flush nfs_close VOP_CLOSE vn_closefile fdrop closef fdcloseexec sys_execve Fix the issue by checking (p->p_flag & P_SUSPSINGLE) instead of (p->p_p->ps_single != NULL) in sleep_setup_signal(). The former is more selective than the latter and allows the thread that invokes execve(2) enter sleep normally. Bug report, change bisecting and testing help by Pavel Korovin OK claudio@ mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_synch.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index efb012278b1..bb77ee31048 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.166 2020/03/20 17:13:51 cheloha Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.167 2020/03/23 15:42:10 visa Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -480,7 +480,7 @@ sleep_setup_signal(struct sleep_state *sls)
* stopped, p->p_wchan will be 0 upon return from CURSIG.
*/
atomic_setbits_int(&p->p_flag, P_SINTR);
- if (p->p_p->ps_single != NULL || (sls->sls_sig = CURSIG(p)) != 0) {
+ if ((p->p_flag & P_SUSPSINGLE) || (sls->sls_sig = CURSIG(p)) != 0) {
unsleep(p);
p->p_stat = SONPROC;
sls->sls_do_sleep = 0;