summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2013-06-01 16:04:46 +0000
committertedu <tedu@openbsd.org>2013-06-01 16:04:46 +0000
commit78aa712ea0775a38fe176de2112a229f97dbe677 (patch)
treece620d292ca0ee44cf78fea100fbefda8f5f71ec /sys/kern/kern_fork.c
parentMinor cleanup, do not set values to 0 twice. (diff)
downloadwireguard-openbsd-78aa712ea0775a38fe176de2112a229f97dbe677.tar.xz
wireguard-openbsd-78aa712ea0775a38fe176de2112a229f97dbe677.zip
As found by kurt, there's a twisty race between exit1 and fork1
with threaded processes. Fix this by checking for an attempt to go single threaded in fork1 and account for the new thread as well. ok espie guenther kurt
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index fbe7dcf19d4..dd4de7f0c9b 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.146 2013/04/06 03:44:34 tedu Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.147 2013/06/01 16:04:46 tedu Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -325,6 +325,14 @@ fork1(struct proc *curp, int exitsig, int flags, void *stack, pid_t *tidptr,
p->p_p = pr = curpr;
TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
pr->ps_refcnt++;
+ /*
+ * if somebody else wants to take us to single threaded mode,
+ * count ourselves in.
+ */
+ if (pr->ps_single) {
+ curpr->ps_singlecount++;
+ atomic_setbits_int(&p->p_flag, P_SUSPSINGLE);
+ }
} else {
process_new(p, curpr);
pr = p->p_p;