aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Gritton <jamie@FreeBSD.org>2026-06-19 19:45:27 +0000
committerJamie Gritton <jamie@FreeBSD.org>2026-06-19 19:45:27 +0000
commite91e8ebefadcce9d57c8ff945ff70050cbbe1ce1 (patch)
treeb3dd41bf5252d385b56c9cd763b2763743aead2d
parent9919c1a8ebd7da0aa86c6475446a7af255ecb17a (diff)
jail: call PR_METHOD_ATTACH again (with old jail) if the first call fails
jail_attach lets modules do attachment-specific work by calling osd_jail_call(PR_METHOD_ATTACH). If one of the modules returns an error, the call needs to be repeated with the thread's current prison, so possible earlier modules and undo any changes they may have made. MFC after: 5 days
-rw-r--r--sys/kern/kern_jail.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index a8d44012db0f..9e6d72ac7157 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3160,10 +3160,8 @@ do_jail_attach(struct thread *td, struct prison *pr, int drflags)
/* Let modules do whatever they need to prepare for attaching. */
error = osd_jail_call(pr, PR_METHOD_ATTACH, td);
- if (error) {
- prison_deref(pr, drflags);
- return (error);
- }
+ if (error)
+ goto e_revert_osd;
sx_unlock(&allprison_lock);
drflags &= ~(PD_LIST_SLOCKED | PD_LIST_XLOCKED);
@@ -3236,8 +3234,10 @@ do_jail_attach(struct thread *td, struct prison *pr, int drflags)
VOP_UNLOCK(pr->pr_root);
e_revert_osd:
/* Tell modules this thread is still in its old jail after all. */
- sx_slock(&allprison_lock);
- drflags |= PD_LIST_SLOCKED;
+ if (!(drflags & (PD_LIST_SLOCKED | PD_LIST_XLOCKED))) {
+ sx_slock(&allprison_lock);
+ drflags |= PD_LIST_SLOCKED;
+ }
(void)osd_jail_call(td->td_ucred->cr_prison, PR_METHOD_ATTACH, td);
prison_deref(pr, drflags);
return (error);