From 7f4e724829e556fc646056669c2af3551b7e8724 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Sat, 26 Dec 2020 20:49:30 -0800 Subject: [PATCH] jail: add a missing lock around an osd_jail_call(). allprison_lock should be at least held shared when jail OSD methods are called. Add a shared lock around one such call where that wasn't the case. In another such call, change an exclusive lock grab to be shared in what is likely the more common case. --- sys/kern/kern_jail.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index a140b6f537d1..fb77cf87126d 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2498,8 +2498,9 @@ do_jail_attach(struct thread *td, struct prison *pr) VOP_UNLOCK(pr->pr_root); e_revert_osd: /* Tell modules this thread is still in its old jail after all. */ + sx_slock(&allprison_lock); (void)osd_jail_call(td->td_ucred->cr_prison, PR_METHOD_ATTACH, td); - prison_deref(pr, PD_DEREF | PD_DEUREF); + prison_deref(pr, PD_DEREF | PD_DEUREF | PD_LIST_SLOCKED); return (error); } @@ -2687,8 +2688,13 @@ prison_deref(struct prison *pr, int flags) */ if (lasturef) { if (!(flags & (PD_LIST_SLOCKED | PD_LIST_XLOCKED))) { - sx_xlock(&allprison_lock); - flags |= PD_LIST_XLOCKED; + if (ref > 1) { + sx_slock(&allprison_lock); + flags |= PD_LIST_SLOCKED; + } else { + sx_xlock(&allprison_lock); + flags |= PD_LIST_XLOCKED; + } } (void)osd_jail_call(pr, PR_METHOD_REMOVE, NULL); mtx_lock(&pr->pr_mtx);