diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1688,8 +1688,12 @@ #ifdef VIMAGE /* Allocate a new vnet if specified. */ - pr->pr_vnet = (pr_flags & PR_VNET) - ? vnet_alloc() : ppr->pr_vnet; + if (pr_flags & PR_VNET) { + pr->pr_vnet = vnet_alloc(); + pr->pr_flags |= PR_VNET_ROOT; + } else { + pr->pr_vnet = ppr->pr_vnet; + } #endif /* * Allocate a dedicated cpuset for each jail. @@ -3207,9 +3211,12 @@ * Removing a prison frees references * from its parent. */ + ppr = pr->pr_parent; + pr->pr_parent = NULL; mtx_unlock(&pr->pr_mtx); + + pr = ppr; flags &= ~PD_LOCKED; - pr = pr->pr_parent; flags |= PD_DEREF | PD_DEUREF; continue; } @@ -3236,7 +3243,7 @@ */ TAILQ_FOREACH_SAFE(rpr, &freeprison, pr_list, tpr) { #ifdef VIMAGE - if (rpr->pr_vnet != rpr->pr_parent->pr_vnet) + if (rpr->pr_flags & PR_VNET_ROOT) vnet_destroy(rpr->pr_vnet); #endif if (rpr->pr_root != NULL) diff --git a/sys/sys/jail.h b/sys/sys/jail.h --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -234,6 +234,8 @@ /* by this jail or an ancestor */ #define PR_COMPLETE_PROC 0x08000000 /* prison_complete called from */ /* prison_proc_free, releases uref */ +#define PR_VNET_ROOT 0x10000000 /* prison's parent has a different */ + /* vnet */ /* * Flags for pr_allow