jail: Handle a parent jail when a child is added to it

It's possible when adding a jail that its dying parent comes back to
life.  Only allow that to happen when JAIL_DYING is specified.  And if
it does happen, call PR_METHOD_CREATE on it.
This commit is contained in:
Jamie Gritton 2021-01-28 21:51:09 -08:00
parent bf59049c27
commit c050ea803e

View File

@ -1105,6 +1105,14 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
"jail \"%s\" not found", name);
goto done_deref;
}
if (!(flags & JAIL_DYING) &&
!prison_isalive(ppr)) {
mtx_unlock(&ppr->pr_mtx);
error = ENOENT;
vfs_opterror(opts,
"jail \"%s\" is dying", name);
goto done_deref;
}
mtx_unlock(&ppr->pr_mtx);
*namelc = '.';
}
@ -1200,8 +1208,18 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
goto done_deref;
}
prison_hold(ppr);
refcount_acquire(&ppr->pr_uref);
mtx_unlock(&ppr->pr_mtx);
if (refcount_acquire(&ppr->pr_uref))
mtx_unlock(&ppr->pr_mtx);
else {
/* This brings the parent back to life. */
mtx_unlock(&ppr->pr_mtx);
error = osd_jail_call(ppr, PR_METHOD_CREATE, opts);
if (error) {
pr = ppr;
drflags |= PD_DEREF | PD_DEUREF;
goto done_deref;
}
}
if (jid == 0 && (jid = get_next_prid(&inspr)) == 0) {
error = EAGAIN;