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 @@ -777,19 +777,19 @@ /* * Restrict a prison's IP address list with its parent's, possibly replacing - * it. Return true if the replacement buffer was used (or should redo). + * it. Return true if succeed, otherwise should redo. * kern_jail_set() helper. */ static bool prison_ip_restrict(struct prison *pr, const pr_family_t af, - struct prison_ip *new) + struct prison_ip **newp) { const struct prison_ip *ppip = pr->pr_parent->pr_addrs[af]; const struct prison_ip *pip = pr->pr_addrs[af]; int (*const cmp)(const void *, const void *) = pr_families[af].cmp; const size_t size = pr_families[af].size; + struct prison_ip *new = newp != NULL ? *newp : NULL; uint32_t ips; - bool alloced, used; mtx_assert(&pr->pr_mtx, MA_OWNED); @@ -803,22 +803,21 @@ if (ppip == NULL) { if (pip != NULL) prison_ip_set(pr, af, NULL); - return (false); + return (true); } if (!(pr->pr_flags & pr_families[af].ip_flag)) { if (new == NULL) { new = prison_ip_alloc(af, ppip->ips, M_NOWAIT); if (new == NULL) - return (true); /* redo */ - used = false; - } else - used = true; + return (false); /* Redo */ + } /* This has no user settings, so just copy the parent's list. */ MPASS(new->ips == ppip->ips); bcopy(ppip + 1, new + 1, ppip->ips * size); prison_ip_set(pr, af, new); - return (used); + if (newp != NULL) + *newp = NULL; /* Used */ } else if (pip != NULL) { /* Remove addresses that aren't in the parent. */ int i; @@ -826,16 +825,10 @@ i = 0; /* index in pip */ ips = 0; /* index in new */ - used = true; if (new == NULL) { new = prison_ip_alloc(af, pip->ips, M_NOWAIT); if (new == NULL) - return (true); /* redo */ - used = false; - alloced = true; - } else { - used = true; - alloced = false; + return (false); /* Redo */ } for (int pi = 0; pi < ppip->ips; pi++) @@ -873,10 +866,9 @@ } } if (ips == 0) { - if (alloced) + if (newp == NULL || *newp == NULL) prison_ip_free(new); new = NULL; - used = false; } else { /* Shrink to real size */ KASSERT((new->ips >= ips), @@ -884,9 +876,10 @@ new->ips = ips; } prison_ip_set(pr, af, new); - return (used); + if (newp != NULL) + *newp = NULL; /* Used */ } - return (false); + return (true); } /* @@ -984,10 +977,12 @@ int jid, jsys, len, level; int childmax, osreldt, rsnum, slevel; #ifdef INET - int ip4s, redo_ip4; + int ip4s; + bool redo_ip4; #endif #ifdef INET6 - int ip6s, redo_ip6; + int ip6s; + bool redo_ip6; #endif uint64_t pr_allow, ch_allow, pr_flags, ch_flags; uint64_t pr_allow_diff; @@ -1864,7 +1859,7 @@ /* Set the parameters of the prison. */ #ifdef INET - redo_ip4 = 0; + redo_ip4 = false; if (pr_flags & PR_IP4_USER) { pr->pr_flags |= PR_IP4; prison_ip_set(pr, PR_INET, ip4); @@ -1876,15 +1871,15 @@ continue; } #endif - if (prison_ip_restrict(tpr, PR_INET, NULL)) { - redo_ip4 = 1; + if (!prison_ip_restrict(tpr, PR_INET, NULL)) { + redo_ip4 = true; descend = 0; } } } #endif #ifdef INET6 - redo_ip6 = 0; + redo_ip6 = false; if (pr_flags & PR_IP6_USER) { pr->pr_flags |= PR_IP6; prison_ip_set(pr, PR_INET6, ip6); @@ -1896,8 +1891,8 @@ continue; } #endif - if (prison_ip_restrict(tpr, PR_INET6, NULL)) { - redo_ip6 = 1; + if (!prison_ip_restrict(tpr, PR_INET6, NULL)) { + redo_ip6 = true; descend = 0; } } @@ -2041,9 +2036,10 @@ #ifdef INET while (redo_ip4) { ip4s = pr->pr_addrs[PR_INET]->ips; + MPASS(ip4 == NULL); ip4 = prison_ip_alloc(PR_INET, ip4s, M_WAITOK); mtx_lock(&pr->pr_mtx); - redo_ip4 = 0; + redo_ip4 = false; FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) { #ifdef VIMAGE if (tpr->pr_flags & PR_VNET) { @@ -2051,12 +2047,7 @@ continue; } #endif - if (prison_ip_restrict(tpr, PR_INET, ip4)) { - if (ip4 != NULL) - ip4 = NULL; - else - redo_ip4 = 1; - } + redo_ip4 = !prison_ip_restrict(tpr, PR_INET, &ip4); } mtx_unlock(&pr->pr_mtx); } @@ -2064,9 +2055,10 @@ #ifdef INET6 while (redo_ip6) { ip6s = pr->pr_addrs[PR_INET6]->ips; + MPASS(ip6 == NULL); ip6 = prison_ip_alloc(PR_INET6, ip6s, M_WAITOK); mtx_lock(&pr->pr_mtx); - redo_ip6 = 0; + redo_ip6 = false; FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend) { #ifdef VIMAGE if (tpr->pr_flags & PR_VNET) { @@ -2074,12 +2066,7 @@ continue; } #endif - if (prison_ip_restrict(tpr, PR_INET6, ip6)) { - if (ip6 != NULL) - ip6 = NULL; - else - redo_ip6 = 1; - } + redo_ip6 = !prison_ip_restrict(tpr, PR_INET6, &ip6); } mtx_unlock(&pr->pr_mtx); }