From 86c583514576a3099d79bc4601e2fc7824fe054f Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 15 Feb 2021 09:35:59 +0000 Subject: [PATCH] Move single_thread_set() out of KERNEL_LOCK(). Use the SCHED_LOCK() to ensure `ps_thread' isn't being modified by a sibling when entering tsleep(9) w/o KERNEL_LOCK(). ok visa@ --- sys/kern/kern_exit.c | 5 ++++- sys/kern/kern_fork.c | 6 +++--- sys/kern/kern_sig.c | 7 +------ sys/sys/proc.h | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 94e3981151f..cbb116e6dcc 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.195 2021/02/08 10:51:01 mpi Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.196 2021/02/15 09:35:59 mpi Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -124,6 +124,7 @@ exit1(struct proc *p, int xexit, int xsig, int flags) { struct process *pr, *qr, *nqr; struct rusage *rup; + int s; atomic_setbits_int(&p->p_flag, P_WEXIT); @@ -161,7 +162,9 @@ exit1(struct proc *p, int xexit, int xsig, int flags) } /* unlink ourselves from the active threads */ + SCHED_LOCK(s); TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link); + SCHED_UNLOCK(s); if ((p->p_flag & P_THREAD) == 0) { /* main thread gotta wait because it has the pid, et al */ while (pr->ps_refcnt > 1) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index ee11b705d8f..2c84a9abf52 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.233 2021/02/11 13:40:28 otto Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.234 2021/02/15 09:35:59 mpi Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -558,13 +558,13 @@ thread_fork(struct proc *curp, void *stack, void *tcb, pid_t *tidptr, LIST_INSERT_HEAD(&allproc, p, p_list); LIST_INSERT_HEAD(TIDHASH(p->p_tid), p, p_hash); - TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link); + SCHED_LOCK(s); + TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link); /* * if somebody else wants to take us to single threaded mode, * count ourselves in. */ - SCHED_LOCK(s); if (pr->ps_single) { atomic_inc_int(&pr->ps_singlecount); atomic_setbits_int(&p->p_flag, P_SUSPSINGLE); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 6435794c833..97d99967826 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.272 2021/02/08 10:51:01 mpi Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.273 2021/02/15 09:35:59 mpi Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1209,11 +1209,7 @@ issignal(struct proc *p) signum != SIGKILL) { pr->ps_xsig = signum; - if (dolock) - KERNEL_LOCK(); single_thread_set(p, SINGLE_PTRACE, 0); - if (dolock) - KERNEL_UNLOCK(); if (dolock) SCHED_LOCK(s); @@ -2009,7 +2005,6 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep) struct proc *q; int error, s; - KERNEL_ASSERT_LOCKED(); KASSERT(curproc == p); SCHED_LOCK(s); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 43178052472..462af504f33 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.308 2021/02/08 10:51:02 mpi Exp $ */ +/* $OpenBSD: proc.h,v 1.309 2021/02/15 09:35:59 mpi Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -167,7 +167,7 @@ struct process { struct ucred *ps_ucred; /* Process owner's identity. */ LIST_ENTRY(process) ps_list; /* List of all processes. */ - TAILQ_HEAD(,proc) ps_threads; /* Threads in this process. */ + TAILQ_HEAD(,proc) ps_threads; /* [K|S] Threads in this process. */ LIST_ENTRY(process) ps_pglist; /* List of processes in pgrp. */ struct process *ps_pptr; /* Pointer to parent process. */ -- 2.20.1