diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2020-03-23 15:42:11 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2020-03-23 15:42:11 +0000 |
commit | 71f63dcb2a44ed48f5f764c229061a0de6d8a499 (patch) | |
tree | 729ba07ce2a6210621bd7f05760f3b77c8ef7f6d /sys/kern | |
parent | 249d621757d2e1fe2169ff6529ee1851a1fd338a (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/kern')
-rw-r--r-- | sys/kern/kern_synch.c | 4 |
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; |