From owner-svn-src-projects@FreeBSD.ORG Tue Jun 16 22:39:58 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 53A44106566B; Tue, 16 Jun 2009 22:39:58 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4261B8FC21; Tue, 16 Jun 2009 22:39:58 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5GMdw1w054072; Tue, 16 Jun 2009 22:39:58 GMT (envelope-from brooks@svn.freebsd.org) Received: (from brooks@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5GMdwFU054070; Tue, 16 Jun 2009 22:39:58 GMT (envelope-from brooks@svn.freebsd.org) Message-Id: <200906162239.n5GMdwFU054070@svn.freebsd.org> From: Brooks Davis Date: Tue, 16 Jun 2009 22:39:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194309 - projects/ngroups/sys/netinet/ipfw X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jun 2009 22:39:58 -0000 Author: brooks Date: Tue Jun 16 22:39:57 2009 New Revision: 194309 URL: http://svn.freebsd.org/changeset/base/194309 Log: Instead of caching an incomplete copy of the interesting bits of struct ucred, just grab a reference and cache a pointer to the real deal. Modified: projects/ngroups/sys/netinet/ipfw/ip_fw2.c Modified: projects/ngroups/sys/netinet/ipfw/ip_fw2.c ============================================================================== --- projects/ngroups/sys/netinet/ipfw/ip_fw2.c Tue Jun 16 22:35:16 2009 (r194308) +++ projects/ngroups/sys/netinet/ipfw/ip_fw2.c Tue Jun 16 22:39:57 2009 (r194309) @@ -135,20 +135,6 @@ static uma_zone_t ipfw_dyn_rule_zone; struct ip_fw *ip_fw_default_rule; /* - * Data structure to cache our ucred related - * information. This structure only gets used if - * the user specified UID/GID based constraints in - * a firewall rule. - */ -#define FW_NGROUPS 16 -struct ip_fw_ugid { - gid_t fw_groups[FW_NGROUPS]; /* XXX: should be dynamic */ - int fw_ngroups; - uid_t fw_uid; - int fw_prid; -}; - -/* * list of rules for layer 3 */ #ifdef VIMAGE_GLOBALS @@ -2010,22 +1996,10 @@ dump_table(struct ip_fw_chain *ch, ipfw_ return (0); } -static void -fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp) -{ - struct ucred *cr; - - cr = inp->inp_cred; - ugp->fw_prid = jailed(cr) ? cr->cr_prison->pr_id : -1; - ugp->fw_uid = cr->cr_uid; - ugp->fw_ngroups = MIN(cr->cr_ngroups, FW_NGROUPS); - bcopy(cr->cr_groups, ugp->fw_groups, sizeof(gid_t) * ugp->fw_ngroups); -} - static int check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif, struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip, - u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp, + u_int16_t src_port, struct ucred **uc, int *ugid_lookupp, struct inpcb *inp) { INIT_VNET_INET(curvnet); @@ -2033,7 +2007,6 @@ check_uidgid(ipfw_insn_u32 *insn, int pr int wildcard; struct inpcb *pcb; int match; - gid_t *gp; /* * Check to see if the UDP or TCP stack supplied us with @@ -2043,7 +2016,7 @@ check_uidgid(ipfw_insn_u32 *insn, int pr if (inp && *ugid_lookupp == 0) { INP_LOCK_ASSERT(inp); if (inp->inp_socket != NULL) { - fill_ugid_cache(inp, ugp); + *uc=crhold(inp->inp_cred); *ugid_lookupp = 1; } else *ugid_lookupp = -1; @@ -2076,7 +2049,7 @@ check_uidgid(ipfw_insn_u32 *insn, int pr dst_ip, htons(dst_port), wildcard, NULL); if (pcb != NULL) { - fill_ugid_cache(pcb, ugp); + *uc=crhold(inp->inp_cred); *ugid_lookupp = 1; } INP_INFO_RUNLOCK(pi); @@ -2092,16 +2065,11 @@ check_uidgid(ipfw_insn_u32 *insn, int pr } } if (insn->o.opcode == O_UID) - match = (ugp->fw_uid == (uid_t)insn->d[0]); - else if (insn->o.opcode == O_GID) { - for (gp = ugp->fw_groups; - gp < &ugp->fw_groups[ugp->fw_ngroups]; gp++) - if (*gp == (gid_t)insn->d[0]) { - match = 1; - break; - } - } else if (insn->o.opcode == O_JAIL) - match = (ugp->fw_prid == (int)insn->d[0]); + match = ((*uc)->cr_uid == (uid_t)insn->d[0]); + else if (insn->o.opcode == O_GID) + match = groupmember((gid_t)insn->d[0], *uc); + else if (insn->o.opcode == O_JAIL) + match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]); return match; } @@ -2179,8 +2147,8 @@ ipfw_chk(struct ip_fw_args *args) * these types of constraints, as well as decrease contention * on pcb related locks. */ - struct ip_fw_ugid fw_ugid_cache; - int ugid_lookup = 0; + struct ucred *ucred_cache = NULL; + int ucred_lookup = 0; /* * divinput_flags If non-zero, set to the IP_FW_DIVERT_*_FLAG @@ -2642,8 +2610,8 @@ check_body: (ipfw_insn_u32 *)cmd, proto, oif, dst_ip, dst_port, - src_ip, src_port, &fw_ugid_cache, - &ugid_lookup, args->inp); + src_ip, src_port, &ucred_cache, + &ucred_lookup, args->inp); break; case O_RECV: @@ -3271,6 +3239,8 @@ check_body: /* XXX statistic */ /* drop packet */ IPFW_RUNLOCK(chain); + if (ucred_cache != NULL) + crfree(ucred_cache); return (IP_FW_DENY); } dt = (struct divert_tag *)(mtag+1); @@ -3476,6 +3446,8 @@ next_rule:; /* try next rule */ } /* end of outer for, scan rules */ printf("ipfw: ouch!, skip past end of rules, denying packet\n"); IPFW_RUNLOCK(chain); + if (ucred_cache != NULL) + crfree(ucred_cache); return (IP_FW_DENY); done: @@ -3484,6 +3456,8 @@ done: f->bcnt += pktlen; f->timestamp = time_uptime; IPFW_RUNLOCK(chain); + if (ucred_cache != NULL) + crfree(ucred_cache); return (retval); pullup_failed: