From owner-p4-projects@FreeBSD.ORG Sun Oct 11 10:38:58 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D8A711065676; Sun, 11 Oct 2009 10:38:57 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 841D4106566B for ; Sun, 11 Oct 2009 10:38:57 +0000 (UTC) (envelope-from trasz@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 71F318FC19 for ; Sun, 11 Oct 2009 10:38:57 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n9BAcvEK003303 for ; Sun, 11 Oct 2009 10:38:57 GMT (envelope-from trasz@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n9BAcvVu003301 for perforce@freebsd.org; Sun, 11 Oct 2009 10:38:57 GMT (envelope-from trasz@freebsd.org) Date: Sun, 11 Oct 2009 10:38:57 GMT Message-Id: <200910111038.n9BAcvVu003301@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to trasz@freebsd.org using -f From: Edward Tomasz Napierala To: Perforce Change Reviews Cc: Subject: PERFORCE change 169384 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Oct 2009 10:38:58 -0000 http://perforce.freebsd.org/chv.cgi?CH=169384 Change 169384 by trasz@trasz_victim on 2009/10/11 10:38:24 Get rid of per-group limits. The code implementing them was bad in the first place, and then got horribly broken after Brooks changed the way group ids are stored in the ucred. Some of the infrastructure - 'struct gidinfo', giwhatever() routines etc - are left alone; they are ok and will be reused when per-group limits support get reimplemented. Affected files ... .. //depot/projects/soc2009/trasz_limits/TODO#13 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#16 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_exec.c#9 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#16 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#65 edit .. //depot/projects/soc2009/trasz_limits/sys/kern/kern_prot.c#24 edit .. //depot/projects/soc2009/trasz_limits/sys/sys/ucred.h#10 edit Differences ... ==== //depot/projects/soc2009/trasz_limits/TODO#13 (text+ko) ==== @@ -2,10 +2,9 @@ - Make the limits lists protected by the subjects lock (e.g. process lock) instead of hrl_lock. - - Make sure we have all the gidinfos we need in the 'struct ucred'. + - Bring back per-group limits. - Fix up (add/remove resource counters) when: - - Adding a group to a process, - Removing a group from a process, - Moving a process into a jail. - Changing [re]uid; ==== //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#16 (text+ko) ==== @@ -465,8 +465,6 @@ /* Create credentials. */ p->p_ucred = crget(); p->p_ucred->cr_ngroups = 1; /* group 0 */ - if (p->p_ucred->cr_gidinfos != NULL) - p->p_ucred->cr_gidinfos[0] = gifind(0); p->p_ucred->cr_uidinfo = uifind(0); p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = &prison0; ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_exec.c#9 (text+ko) ==== @@ -325,7 +325,6 @@ struct nameidata nd; struct ucred *newcred = NULL, *oldcred; struct uidinfo *euip; - struct gidinfo *egip; register_t *stack_base; int error, len = 0, i; struct image_params image_params, *imgp; @@ -564,7 +563,6 @@ */ newcred = crget(); euip = uifind(attr.va_uid); - egip = gifind(attr.va_gid); i = imgp->args->begin_envv - imgp->args->begin_argv; /* Cache arguments if they fit inside our allowance */ if (ps_arg_cache_limit >= i + sizeof(struct pargs)) { @@ -693,7 +691,7 @@ if (attr.va_mode & S_ISUID) change_euid(newcred, euip); if (attr.va_mode & S_ISGID) - change_egid(newcred, egip); + change_egid(newcred, attr.va_gid); #ifdef MAC if (will_transition) { mac_vnode_execve_transition(oldcred, newcred, imgp->vp, @@ -822,7 +820,6 @@ * Free any resources malloc'd earlier that we didn't use. */ uifree(euip); - gifree(egip); if (newcred == NULL) crfree(oldcred); else ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#16 (text+ko) ==== @@ -770,7 +770,7 @@ hrl_proc_exiting(p); /* - * Free credentials, arguments and sigacts. + * Free credentials, arguments, and sigacts. */ crfree(p->p_ucred); p->p_ucred = NULL; ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_hrl.c#65 (text+ko) ==== @@ -59,12 +59,6 @@ #define HRL_DEFAULT_BUFSIZE 4096 #define HRL_LOG_BUFSIZE 128 -int hrl_group_accounting = 0; - -TUNABLE_INT("kern.hrl_group_accounting", &hrl_group_accounting); -SYSCTL_INT(_kern, OID_AUTO, hrl_group_accounting, CTLFLAG_RD, - &hrl_group_accounting, 0, ""); - struct dict { const char *d_name; int d_value; @@ -127,7 +121,7 @@ static void hrl_assert_proc(const struct proc *p __unused) { - int i, resource; + int resource; struct ucred *cred; struct prison *pr; @@ -148,17 +142,6 @@ p->p_usage.hu_resources[resource], ("resource usage propagation meltdown")); } - if (hrl_group_accounting) { - for (i = 0; i < cred->cr_ngroups; i++) { - for (resource = 0; resource <= HRL_RESOURCE_MAX; resource++) { - KASSERT(cred->cr_gidinfos[i]->gi_usage.hu_resources[resource] >= 0, - ("resource usage propagation meltdown")); - KASSERT(cred->cr_gidinfos[i]->gi_usage.hu_resources[resource] >= - p->p_usage.hu_resources[resource], - ("resource usage propagation meltdown")); - } - } - } } #endif /* DIAGNOSTIC */ @@ -258,8 +241,8 @@ static int64_t hrl_available_resource(const struct proc *p, const struct hrl_rule *rule) { - int resource, i; - int64_t available = INT64_MAX, found = 0; + int resource; + int64_t available = INT64_MAX; struct ucred *cred = p->p_ucred; mtx_assert(&hrl_lock, MA_OWNED); @@ -274,20 +257,6 @@ available = rule->hr_amount - cred->cr_ruidinfo->ui_usage.hu_resources[resource]; break; - case HRL_SUBJECT_TYPE_GROUP: - if (hrl_group_accounting) { - for (i = 0; i < cred->cr_ngroups; i++) { - if (cred->cr_gidinfos[i] != - rule->hr_subject.hs_gip) - continue; - - found = 1; - available = rule->hr_amount - - cred->cr_gidinfos[i]->gi_usage.hu_resources[resource]; - } - KASSERT(found, ("hrl_available_resource: group not found")); - } - break; case HRL_SUBJECT_TYPE_LOGINCLASS: available = rule->hr_amount - cred->cr_loginclass->lc_usage.hu_resources[resource]; @@ -475,7 +444,7 @@ int hrl_alloc(struct proc *p, int resource, uint64_t amount) { - int i, j, error; + int error; struct ucred *cred; struct prison *pr; @@ -498,25 +467,6 @@ for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) pr->pr_usage.hu_resources[resource] += amount; cred->cr_loginclass->lc_usage.hu_resources[resource] += amount; - /* - * XXX: Slow. - */ - if (hrl_group_accounting) { - for (i = 0; i < cred->cr_ngroups; i++) { - /* - * Make sure we don't account a group more than once - * if it appears in cr_groups[] more than once. - */ - for (j = 0; j < i; j++) { - if (cred->cr_groups[i] == cred->cr_groups[j]) - goto skip_group; - } - cred->cr_gidinfos[i]->gi_usage.hu_resources[resource] += - amount; -skip_group: - continue; - } - } #ifdef DIAGNOSTIC hrl_assert_proc(p); #endif @@ -535,7 +485,7 @@ int hrl_allocated(struct proc *p, int resource, uint64_t amount) { - int i, j, error; + int error; int64_t diff; struct ucred *cred; struct prison *pr; @@ -562,25 +512,6 @@ for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) pr->pr_usage.hu_resources[resource] += diff; cred->cr_loginclass->lc_usage.hu_resources[resource] += diff; - /* - * XXX: Slow. - */ - if (hrl_group_accounting) { - for (i = 0; i < cred->cr_ngroups; i++) { - /* - * Make sure we don't account a group more than once - * if it appears in cr_groups[] more than once. - */ - for (j = 0; j < i; j++) { - if (cred->cr_groups[i] == cred->cr_groups[j]) - goto skip_group; - } - cred->cr_gidinfos[i]->gi_usage.hu_resources[resource] += - diff; -skip_group: - continue; - } - } #ifdef DIAGNOSTIC hrl_assert_proc(p); #endif @@ -595,7 +526,6 @@ void hrl_free(struct proc *p, int resource, uint64_t amount) { - int i, j; struct ucred *cred; struct prison *pr; @@ -617,25 +547,6 @@ for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) pr->pr_usage.hu_resources[resource] -= amount; cred->cr_loginclass->lc_usage.hu_resources[resource] -= amount; - /* - * XXX: Slow. - */ - if (hrl_group_accounting) { - for (i = 0; i < cred->cr_ngroups; i++) { - /* - * Make sure we don't account a group more than once - * if it appears in cr_groups[] more than once. - */ - for (j = 0; j < i; j++) { - if (cred->cr_groups[i] == cred->cr_groups[j]) - goto skip_group; - } - cred->cr_gidinfos[i]->gi_usage.hu_resources[resource] -= - amount; -skip_group: - continue; - } - } #ifdef DIAGNOSTIC hrl_assert_proc(p); #endif @@ -1149,7 +1060,6 @@ return (rule); } - /* * Link a rule with subjects to which it applies. */ @@ -1165,8 +1075,8 @@ KASSERT(hrl_rule_fully_specified(rule), ("rule not fully specified")); - if ((rule->hr_subject_type == HRL_SUBJECT_TYPE_GROUP || - rule->hr_per == HRL_SUBJECT_TYPE_GROUP) && !hrl_group_accounting) + if (rule->hr_subject_type == HRL_SUBJECT_TYPE_GROUP || + rule->hr_per == HRL_SUBJECT_TYPE_GROUP) return (EOPNOTSUPP); if (rule->hr_action == HRL_ACTION_DELAY) @@ -1734,7 +1644,7 @@ void hrl_proc_ucred_changing(struct proc *p, struct ucred *newcred) { - int error, i; + int error; struct hrl_limit *limit; struct uidinfo *olduip, *newuip; struct loginclass *oldlc, *newlc; @@ -1765,17 +1675,6 @@ error = hrl_limit_add_locked(&p->p_limits, limit->hl_rule); KASSERT(error == 0, ("XXX: better error handling needed")); } - if (hrl_group_accounting) { - for (i = 0; i < newcred->cr_ngroups; i++) { - LIST_FOREACH(limit, - &newcred->cr_gidinfos[i]->gi_limits, hl_next) { - error = hrl_limit_add_locked(&p->p_limits, - limit->hl_rule); - KASSERT(error == 0, - ("XXX: better error handling needed")); - } - } - } /* * Add rules for the current loginclass. @@ -1798,18 +1697,6 @@ } /* - * Fix up per-group resource consumption. - */ - if (hrl_group_accounting) { - for (i = 0; i < p->p_ucred->cr_ngroups; i++) - hrl_usage_subtract( - &p->p_ucred->cr_gidinfos[i]->gi_usage, &p->p_usage); - for (i = 0; i < newcred->cr_ngroups; i++) - hrl_usage_add( - &newcred->cr_gidinfos[i]->gi_usage, &p->p_usage); - } - - /* * Adjust loginclass resource usage information. */ newlc = newcred->cr_loginclass; ==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_prot.c#24 (text+ko) ==== @@ -79,8 +79,6 @@ #include #include -extern int hrl_group_accounting; - static MALLOC_DEFINE(M_CRED, "cred", "credentials"); SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy"); @@ -655,13 +653,11 @@ struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; gid_t gid; - struct gidinfo *gip; int error; gid = uap->gid; AUDIT_ARG_GID(gid); newcred = crget(); - gip = gifind(gid); PROC_LOCK(p); oldcred = crcopysafe(p, newcred); @@ -729,18 +725,16 @@ * Copy credentials so other references do not see our changes. */ if (oldcred->cr_groups[0] != gid) { - change_egid(newcred, gip); + change_egid(newcred, gid); setsugid(p); } change_cred(p, newcred); PROC_UNLOCK(p); - gifree(gip); crfree(oldcred); return (0); fail: PROC_UNLOCK(p); - gifree(gip); crfree(newcred); return (error); } @@ -757,13 +751,11 @@ struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; gid_t egid; - struct gidinfo *egip; int error; egid = uap->egid; AUDIT_ARG_EGID(egid); newcred = crget(); - egip = gifind(egid); PROC_LOCK(p); oldcred = crcopysafe(p, newcred); @@ -779,18 +771,16 @@ goto fail; if (oldcred->cr_groups[0] != egid) { - change_egid(newcred, egip); + change_egid(newcred, egid); setsugid(p); } change_cred(p, newcred); PROC_UNLOCK(p); - gifree(egip); crfree(oldcred); return (0); fail: PROC_UNLOCK(p); - gifree(egip); crfree(newcred); return (error); } @@ -825,8 +815,6 @@ { struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; - struct gidinfo **gidinfos = NULL, **oldgidinfos = NULL; - int i, oldngroups = 0; int error; if (ngrp > NGROUPS) @@ -834,12 +822,6 @@ AUDIT_ARG_GROUPSET(groups, ngrp); newcred = crget(); crextend(newcred, ngrp); - if (hrl_group_accounting) { - gidinfos = malloc(ngrp * sizeof(struct gidinfo *), M_CRED, - M_WAITOK | M_ZERO); - for (i = 0; i < ngrp; i++) - gidinfos[i] = gifind(groups[i]); - } PROC_LOCK(p); oldcred = crcopysafe(p, newcred); @@ -860,53 +842,19 @@ * have the egid in the groups[0]). We risk security holes * when running non-BSD software if we do not do the same. */ - if (hrl_group_accounting) { - oldngroups = newcred->cr_ngroups - 1; - for (i = 0; i < oldngroups; i++) - oldgidinfos[i] = newcred->cr_gidinfos[i + 1]; - } newcred->cr_ngroups = 1; } else { crsetgroups_locked(newcred, ngrp, groups); - if (hrl_group_accounting) { - oldngroups = newcred->cr_ngroups; - for (i = 0; i < oldngroups; i++) - oldgidinfos[i] = newcred->cr_gidinfos[i]; - newcred->cr_ngroups = ngrp; - for (i = 0; i < newcred->cr_ngroups; i++) - newcred->cr_gidinfos[i] = gidinfos[i]; - } } setsugid(p); change_cred(p, newcred); PROC_UNLOCK(p); - if (hrl_group_accounting) { - for (i = 0; i < oldngroups; i++) - gifree(oldgidinfos[i]); - } - /* Don't free gidinfos[]. */ crfree(oldcred); - if (hrl_group_accounting) { - for (i = 0; i < newcred->cr_ngroups; i++) - KASSERT(newcred->cr_gidinfos[i]->gi_gid == newcred->cr_groups[i], ("Whoops.")); - } return (0); fail: PROC_UNLOCK(p); - if (hrl_group_accounting) { - for (i = 0; i < oldngroups; i++) - gifree(oldgidinfos[i]); - free(oldgidinfos, M_CRED); - for (i = 0; i < ngrp; i++) - gifree(gidinfos[i]); - free(gidinfos, M_CRED); - } crfree(newcred); - if (hrl_group_accounting) { - for (i = 0; i < newcred->cr_ngroups; i++) - KASSERT(newcred->cr_gidinfos[i]->gi_gid == newcred->cr_groups[i], ("Whoops.")); - } return (error); } @@ -990,7 +938,6 @@ struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; gid_t egid, rgid; - struct gidinfo *egip; int error; egid = uap->egid; @@ -998,7 +945,6 @@ AUDIT_ARG_EGID(egid); AUDIT_ARG_RGID(rgid); newcred = crget(); - egip = gifind(egid); PROC_LOCK(p); oldcred = crcopysafe(p, newcred); @@ -1016,7 +962,7 @@ goto fail; if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { - change_egid(newcred, egip); + change_egid(newcred, egid); setsugid(p); } if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { @@ -1030,13 +976,11 @@ } change_cred(p, newcred); PROC_UNLOCK(p); - gifree(egip); crfree(oldcred); return (0); fail: PROC_UNLOCK(p); - gifree(egip); crfree(newcred); return (error); } @@ -1138,7 +1082,6 @@ struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; gid_t egid, rgid, sgid; - struct gidinfo *egip; int error; egid = uap->egid; @@ -1148,7 +1091,6 @@ AUDIT_ARG_RGID(rgid); AUDIT_ARG_SGID(sgid); newcred = crget(); - egip = gifind(egid); PROC_LOCK(p); oldcred = crcopysafe(p, newcred); @@ -1171,7 +1113,7 @@ goto fail; if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { - change_egid(newcred, egip); + change_egid(newcred, egid); setsugid(p); } if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { @@ -1184,13 +1126,11 @@ } change_cred(p, newcred); PROC_UNLOCK(p); - gifree(egip); crfree(oldcred); return (0); fail: PROC_UNLOCK(p); - gifree(egip); crfree(newcred); return (error); } @@ -1875,7 +1815,6 @@ void crfree(struct ucred *cr) { - int i; KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); KASSERT(cr->cr_ref != 0xdeadc0de, ("dangling reference to ucred")); @@ -1889,10 +1828,6 @@ uifree(cr->cr_uidinfo); if (cr->cr_ruidinfo != NULL) uifree(cr->cr_ruidinfo); - if (hrl_group_accounting) { - for (i = 0; i < cr->cr_ngroups; i++) - gifree(cr->cr_gidinfos[i]); - } /* * Free a prison, if any. */ @@ -1926,7 +1861,6 @@ void crcopy(struct ucred *dest, struct ucred *src) { - int i; KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); bcopy(&src->cr_startcopy, &dest->cr_startcopy, @@ -1935,10 +1869,6 @@ crsetgroups(dest, src->cr_ngroups, src->cr_groups); uihold(dest->cr_uidinfo); uihold(dest->cr_ruidinfo); - if (hrl_group_accounting) { - for (i = 0; i < dest->cr_ngroups; i++) - gihold(dest->cr_gidinfos[i]); - } prison_hold(dest->cr_prison); loginclass_acquire(dest->cr_loginclass); #ifdef AUDIT @@ -2053,16 +1983,10 @@ cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t)); /* Free the old array. */ - if (cr->cr_groups) { + if (cr->cr_groups) free(cr->cr_groups, M_CRED); - if (hrl_group_accounting) - free(cr->cr_gidinfos, M_CRED); - } cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO); - if (hrl_group_accounting) - cr->cr_gidinfos = malloc(cnt * sizeof(struct gidinfo *), M_CRED, - M_WAITOK | M_ZERO); cr->cr_agroups = cnt; } @@ -2222,15 +2146,10 @@ * duration of the call. */ void -change_egid(struct ucred *newcred, struct gidinfo *egip) +change_egid(struct ucred *newcred, gid_t egid) { - newcred->cr_groups[0] = egip->gi_gid; - if (hrl_group_accounting) { - gihold(egip); - gifree(newcred->cr_gidinfos[0]); - newcred->cr_gidinfos[0] = egip; - } + newcred->cr_groups[0] = egid; } /*- ==== //depot/projects/soc2009/trasz_limits/sys/sys/ucred.h#10 (text+ko) ==== @@ -63,7 +63,6 @@ struct label *cr_label; /* MAC label */ struct auditinfo_addr cr_audit; /* Audit properties. */ gid_t *cr_groups; /* groups */ - struct gidinfo **cr_gidinfos; /* per group resource consumption */ int cr_agroups; /* Available groups */ }; #define NOCRED ((struct ucred *)0) /* no credential available */ @@ -93,7 +92,7 @@ struct proc; void change_cred(struct proc *p, struct ucred *newcred); -void change_egid(struct ucred *newcred, struct gidinfo *egip); +void change_egid(struct ucred *newcred, gid_t egid); void change_euid(struct ucred *newcred, struct uidinfo *euip); void change_rgid(struct ucred *newcred, gid_t rgid); void change_ruid(struct ucred *newcred, struct uidinfo *ruip);