Add an additional struct inpcb * argument to pfil(9) in order to enable

passing along socket information. This is required to work around a LOR with
the socket code which results in an easy reproducible hard lockup with
debug.mpsafenet=1. This commit does *not* fix the LOR, but enables us to do
so later. The missing piece is to turn the filter locking into a leaf lock
and will follow in a seperate (later) commit.

This will hopefully be MT5'ed in order to fix the problem for RELENG_5 in
forseeable future.

Suggested by:		rwatson
A lot of work by:	csjp (he'd be even more helpful w/o mentor-reviews ;)
Reviewed by:		rwatson, csjp
Tested by:		-pf, -ipfw, LINT, csjp and myself
MFC after:		3 days

LOR IDs:		14 - 17 (not fixed yet)
This commit is contained in:
Max Laier 2004-09-29 04:54:33 +00:00
parent 48ac555d83
commit d6a8d58875
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135920
19 changed files with 206 additions and 53 deletions

View File

@ -23,6 +23,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 6.x IS SLOW:
developers choose to disable these features on build machines
to maximize performance.
20040929:
The pfil API has gained an additional argument to pass an inpcb.
You should rebuild all pfil consuming modules: ipfw, ipfilter
and pf.
20040928:
If enabled, the default is now to run named in a chroot
"sandbox." For users with existing configurations in

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 8, 2003
.Dd September 29, 2004
.Dt PFIL 9
.Os
.Sh NAME
@ -59,9 +59,9 @@
.Ft void
.Fn pfil_remove_hook "int (*func)()" "void *arg" "int flags" "struct pfil_head *"
.Ft int
.Fn (*func) "void *arg" "struct mbuf **mp" "struct ifnet *" "int dir"
.Fn (*func) "void *arg" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *"
.Ft int
.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir"
.Fn pfil_run_hooks "struct pfil_head *head" "struct mbuf **mp" "struct ifnet *" "int dir" "struct inpcb *"
.Sh DESCRIPTION
The
.Nm

View File

@ -312,7 +312,8 @@ int dir;
}
# endif
#endif /* __NetBSD_Version >= 105110000 && _KERNEL */
#if (__FreeBSD_version >= 501108) && defined(_KERNEL)
#if (__FreeBSD_version >= 501108) && (__FreeBSD_version < 600004) && \
defined(_KERNEL)
static int
fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
@ -331,7 +332,29 @@ fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
ifp, (dir == PFIL_OUT), mp));
}
# endif
#endif /* __FreeBSD_version >= 501108 */
#elif (__FreeBSD_version >= 600004) && defined(_KERNEL)
static int
fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ip *ip = mtod(*mp, struct ip *);
return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp);
}
# ifdef USE_INET6
# include <netinet/ip6.h>
static int
fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
ifp, (dir == PFIL_OUT), mp));
}
# endif
#endif /* __FreeBSD_version >= 600004 && _KERNEL */
#ifdef _KERNEL
# if defined(IPFILTER_LKM) && !defined(__sgi)
int iplidentify(s)

View File

@ -185,11 +185,19 @@ struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
int pf_test_tcp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
#ifdef __FreeBSD__
struct pf_ruleset **, struct inpcb *);
#else
struct pf_ruleset **);
#endif
int pf_test_udp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
#ifdef __FreeBSD__
struct pf_ruleset **, struct inpcb *);
#else
struct pf_ruleset **);
#endif
int pf_test_icmp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
@ -229,8 +237,13 @@ void pf_route(struct mbuf **, struct pf_rule *, int,
struct ifnet *, struct pf_state *);
void pf_route6(struct mbuf **, struct pf_rule *, int,
struct ifnet *, struct pf_state *);
#ifdef __FreeBSD__
int pf_socket_lookup(uid_t *, gid_t *,
int, struct pf_pdesc *, struct inpcb *);
#else
int pf_socket_lookup(uid_t *, gid_t *,
int, struct pf_pdesc *);
#endif
u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
sa_family_t);
u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
@ -2376,7 +2389,12 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
}
int
#ifdef __FreeBSD__
pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd,
struct inpcb *inp_arg)
#else
pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
#endif
{
struct pf_addr *saddr, *daddr;
u_int16_t sport, dport;
@ -2389,6 +2407,17 @@ pf_socket_lookup(uid_t *uid, gid_t *gid, int direction, struct pf_pdesc *pd)
*uid = UID_MAX;
*gid = GID_MAX;
#ifdef __FreeBSD__
if (inp_arg != NULL) {
INP_LOCK_ASSERT(inp_arg);
if (inp_arg->inp_socket) {
*uid = inp_arg->inp_socket->so_cred->cr_uid;
*gid = inp_arg->inp_socket->so_cred->cr_groups[0];
return (1);
} else
return (0);
}
#endif
switch (pd->proto) {
case IPPROTO_TCP:
sport = pd->hdr.tcp->th_sport;
@ -2663,7 +2692,12 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
int
pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
#ifdef __FreeBSD__
struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
struct inpcb *inp)
#else
struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
#endif
{
struct pf_rule *nr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
@ -2742,12 +2776,20 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
else if ((r->flagset & th->th_flags) != r->flags)
r = TAILQ_NEXT(r, entries);
else if (r->uid.op && (lookup != -1 || (lookup =
#ifdef __FreeBSD__
pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
#else
pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
#endif
!pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
uid))
r = TAILQ_NEXT(r, entries);
else if (r->gid.op && (lookup != -1 || (lookup =
#ifdef __FreeBSD__
pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
#else
pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
#endif
!pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
gid))
r = TAILQ_NEXT(r, entries);
@ -3023,7 +3065,12 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
int
pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
#ifdef __FreeBSD__
struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
struct inpcb *inp)
#else
struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
#endif
{
struct pf_rule *nr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
@ -3099,12 +3146,20 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
else if (r->rule_flag & PFRULE_FRAGMENT)
r = TAILQ_NEXT(r, entries);
else if (r->uid.op && (lookup != -1 || (lookup =
#ifdef __FreeBSD__
pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
#else
pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
#endif
!pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
uid))
r = TAILQ_NEXT(r, entries);
else if (r->gid.op && (lookup != -1 || (lookup =
#ifdef __FreeBSD__
pf_socket_lookup(&uid, &gid, direction, pd, inp), 1)) &&
#else
pf_socket_lookup(&uid, &gid, direction, pd), 1)) &&
#endif
!pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
gid))
r = TAILQ_NEXT(r, entries);
@ -5229,7 +5284,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
if (oifp != ifp) {
#ifdef __FreeBSD__
PF_UNLOCK();
if (pf_test(PF_OUT, ifp, &m0) != PF_PASS) {
if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) {
PF_LOCK();
goto bad;
} else if (m0 == NULL) {
@ -5519,7 +5574,7 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
if (oifp != ifp) {
#ifdef __FreeBSD__
PF_UNLOCK();
if (pf_test6(PF_OUT, ifp, &m0) != PF_PASS) {
if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) {
PF_LOCK();
goto bad;
} else if (m0 == NULL) {
@ -5811,7 +5866,11 @@ pf_add_mbuf_tag(struct mbuf *m, u_int tag)
#ifdef INET
int
#ifdef __FreeBSD__
pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
#else
pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
#endif
{
struct pfi_kif *kif;
u_short action, reason = 0, log = 0;
@ -5925,8 +5984,13 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
a = s->anchor.ptr;
log = s->log;
} else if (s == NULL)
#ifdef __FreeBSD__
action = pf_test_tcp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset, inp);
#else
action = pf_test_tcp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset);
#endif
break;
}
@ -5959,8 +6023,13 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
a = s->anchor.ptr;
log = s->log;
} else if (s == NULL)
#ifdef __FreeBSD__
action = pf_test_udp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset, inp);
#else
action = pf_test_udp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset);
#endif
break;
}
@ -6137,7 +6206,11 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
#ifdef INET6
int
#ifdef __FreeBSD__
pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
#else
pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
#endif
{
struct pfi_kif *kif;
u_short action, reason = 0, log = 0;
@ -6274,8 +6347,13 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
a = s->anchor.ptr;
log = s->log;
} else if (s == NULL)
#ifdef __FreeBSD__
action = pf_test_tcp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset, inp);
#else
action = pf_test_tcp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset);
#endif
break;
}
@ -6308,8 +6386,13 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
a = s->anchor.ptr;
log = s->log;
} else if (s == NULL)
#ifdef __FreeBSD__
action = pf_test_udp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset, inp);
#else
action = pf_test_udp(&r, &s, dir, kif,
m, off, h, &pd, &a, &ruleset);
#endif
break;
}

View File

@ -182,14 +182,14 @@ static void pf_clear_srcnodes(void);
* Wrapper functions for pfil(9) hooks
*/
static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp,
int dir);
int dir, struct inpcb *inp);
static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp,
int dir);
int dir, struct inpcb *inp);
#ifdef INET6
static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp,
int dir);
int dir, struct inpcb *inp);
static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp,
int dir);
int dir, struct inpcb *inp);
#endif
static int hook_pf(void);
@ -3203,7 +3203,8 @@ shutdown_pf(void)
}
static int
pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
/*
* XXX Wed Jul 9 22:03:16 2003 UTC
@ -3222,7 +3223,7 @@ pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
HTONS(h->ip_len);
HTONS(h->ip_off);
}
chk = pf_test(PF_IN, ifp, m);
chk = pf_test(PF_IN, ifp, m, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@ -3237,7 +3238,8 @@ pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
}
static int
pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
/*
* XXX Wed Jul 9 22:03:16 2003 UTC
@ -3261,7 +3263,7 @@ pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
HTONS(h->ip_len);
HTONS(h->ip_off);
}
chk = pf_test(PF_OUT, ifp, m);
chk = pf_test(PF_OUT, ifp, m, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@ -3277,14 +3279,15 @@ pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
#ifdef INET6
static int
pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
/*
* IPv6 does not affected ip_len/ip_off byte order changes.
*/
int chk;
chk = pf_test6(PF_IN, ifp, m);
chk = pf_test6(PF_IN, ifp, m, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;
@ -3293,7 +3296,8 @@ pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
}
static int
pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
/*
* IPv6 does not affected ip_len/ip_off byte order changes.
@ -3305,7 +3309,7 @@ pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir)
in_delayed_cksum(*m);
(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
chk = pf_test6(PF_OUT, ifp, m);
chk = pf_test6(PF_OUT, ifp, m, inp);
if (chk && *m) {
m_freem(*m);
*m = NULL;

View File

@ -54,6 +54,9 @@
#include <netinet/tcp_fsm.h>
struct ip;
#ifdef __FreeBSD__
struct inpcb;
#endif
#define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0)
#define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1)
@ -1453,11 +1456,19 @@ void pf_rm_rule(struct pf_rulequeue *,
struct pf_rule *);
#ifdef INET
#ifdef __FreeBSD__
int pf_test(int, struct ifnet *, struct mbuf **, struct inpcb *);
#else
int pf_test(int, struct ifnet *, struct mbuf **);
#endif
#endif /* INET */
#ifdef INET6
#ifdef __FreeBSD__
int pf_test6(int, struct ifnet *, struct mbuf **, struct inpcb *);
#else
int pf_test6(int, struct ifnet *, struct mbuf **);
#endif
void pf_poolmask(struct pf_addr *, struct pf_addr*,
struct pf_addr *, struct pf_addr *, u_int8_t);
void pf_addr_inc(struct pf_addr *, sa_family_t);

View File

@ -1009,7 +1009,7 @@ bdg_forward(struct mbuf *m0, struct ifnet *dst)
ip->ip_len = ntohs(ip->ip_len);
ip->ip_off = ntohs(ip->ip_off);
if (pfil_run_hooks(&inet_pfil_hook, &m0, src, PFIL_IN) != 0) {
if (pfil_run_hooks(&inet_pfil_hook, &m0, src, PFIL_IN, NULL) != 0) {
/* NB: hook should consume packet */
return NULL;
}

View File

@ -52,7 +52,7 @@ MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock", MTX_DEF);
static int pfil_list_add(pfil_list_t *, struct packet_filter_hook *, int);
static int pfil_list_remove(pfil_list_t *,
int (*)(void *, struct mbuf **, struct ifnet *, int), void *);
int (*)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *);
LIST_HEAD(, pfil_head) pfil_head_list =
LIST_HEAD_INITIALIZER(&pfil_head_list);
@ -113,7 +113,7 @@ PFIL_WUNLOCK(struct pfil_head *ph)
*/
int
pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
int dir)
int dir, struct inpcb *inp)
{
struct packet_filter_hook *pfh;
struct mbuf *m = *mp;
@ -126,7 +126,7 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
pfh = TAILQ_NEXT(pfh, pfil_link)) {
if (pfh->pfil_func != NULL) {
rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir);
rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir, inp);
if (rv != 0 || m == NULL)
break;
}
@ -233,7 +233,7 @@ pfil_head_get(int type, u_long val)
* PFIL_WAITOK OK to call malloc with M_WAITOK.
*/
int
pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *),
void *arg, int flags, struct pfil_head *ph)
{
struct packet_filter_hook *pfh1 = NULL;
@ -305,7 +305,7 @@ pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
* hook list.
*/
int
pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *),
void *arg, int flags, struct pfil_head *ph)
{
int err = 0;
@ -361,7 +361,7 @@ pfil_list_add(pfil_list_t *list, struct packet_filter_hook *pfh1, int flags)
*/
static int
pfil_list_remove(pfil_list_t *list,
int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg)
int (*func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *), void *arg)
{
struct packet_filter_hook *pfh;

View File

@ -40,6 +40,7 @@
struct mbuf;
struct ifnet;
struct inpcb;
/*
* The packet filter hooks are designed for anything to call them to
@ -47,7 +48,7 @@ struct ifnet;
*/
struct packet_filter_hook {
TAILQ_ENTRY(packet_filter_hook) pfil_link;
int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int);
int (*pfil_func)(void *, struct mbuf **, struct ifnet *, int, struct inpcb *);
void *pfil_arg;
int pfil_flags;
};
@ -84,12 +85,12 @@ struct pfil_head {
};
int pfil_run_hooks(struct pfil_head *, struct mbuf **, struct ifnet *,
int);
int, struct inpcb *inp);
int pfil_add_hook(int (*func)(void *, struct mbuf **,
struct ifnet *, int), void *, int, struct pfil_head *);
struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
int pfil_remove_hook(int (*func)(void *, struct mbuf **,
struct ifnet *, int), void *, int, struct pfil_head *);
struct ifnet *, int, struct inpcb *), void *, int, struct pfil_head *);
int pfil_head_register(struct pfil_head *);
int pfil_head_unregister(struct pfil_head *);

View File

@ -359,7 +359,7 @@ ip_fastforward(struct mbuf *m)
if (inet_pfil_hook.ph_busy_count == -1)
goto passin;
if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN) ||
if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL) ||
m == NULL)
return 1;
@ -437,7 +437,7 @@ ip_fastforward(struct mbuf *m)
if (inet_pfil_hook.ph_busy_count == -1)
goto passout;
if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT) || m == NULL) {
if (pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) {
goto consumed;
}

View File

@ -425,6 +425,7 @@ struct ip_fw_args {
struct ipfw_flow_id f_id; /* grabbed from IP header */
u_int32_t retval;
struct inpcb *inp;
};
/*
@ -435,8 +436,8 @@ struct ip_fw_args {
struct sockopt;
struct dn_flow_set;
int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int);
int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int);
int ipfw_check_in(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp);
int ipfw_check_out(void *, struct mbuf **, struct ifnet *, int, struct inpcb *inp);
int ipfw_chk(struct ip_fw_args *);

View File

@ -1532,20 +1532,47 @@ dump_table(ipfw_table *tbl)
return (0);
}
static void
fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
{
struct ucred *cr;
if (inp->inp_socket != NULL) {
cr = inp->inp_socket->so_cred;
ugp->fw_prid = jailed(cr) ?
cr->cr_prison->pr_id : -1;
ugp->fw_uid = cr->cr_uid;
ugp->fw_ngroups = cr->cr_ngroups;
bcopy(cr->cr_groups, ugp->fw_groups,
sizeof(ugp->fw_groups));
}
}
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 *lookup)
struct ip_fw_ugid *ugp, int *lookup, struct inpcb *inp)
{
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
int match;
struct ucred *cr;
gid_t *gp;
/*
* Check to see if the UDP or TCP stack supplied us with
* the PCB. If so, rather then holding a lock and looking
* up the PCB, we can use the one that was supplied.
*/
if (inp && *lookup == 0) {
INP_LOCK_ASSERT(inp);
if (inp->inp_socket != NULL) {
fill_ugid_cache(inp, ugp);
*lookup = 1;
}
}
/*
* If we have already been here and the packet has no
* PCB entry associated with it, then we can safely
@ -1563,7 +1590,7 @@ check_uidgid(ipfw_insn_u32 *insn,
return 0;
match = 0;
if (*lookup == 0) {
INP_INFO_RLOCK(pi); /* XXX LOR with IPFW */
INP_INFO_RLOCK(pi);
pcb = (oif) ?
in_pcblookup_hash(pi,
dst_ip, htons(dst_port),
@ -1576,13 +1603,7 @@ check_uidgid(ipfw_insn_u32 *insn,
if (pcb != NULL) {
INP_LOCK(pcb);
if (pcb->inp_socket != NULL) {
cr = pcb->inp_socket->so_cred;
ugp->fw_prid = jailed(cr) ?
cr->cr_prison->pr_id : -1;
ugp->fw_uid = cr->cr_uid;
ugp->fw_ngroups = cr->cr_ngroups;
bcopy(cr->cr_groups, ugp->fw_groups,
sizeof(ugp->fw_groups));
fill_ugid_cache(pcb, ugp);
*lookup = 1;
}
INP_UNLOCK(pcb);
@ -1938,7 +1959,7 @@ ipfw_chk(struct ip_fw_args *args)
proto, oif,
dst_ip, dst_port,
src_ip, src_port, &fw_ugid_cache,
&ugid_lookup);
&ugid_lookup, args->inp);
break;
case O_RECV:

View File

@ -73,7 +73,8 @@ ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
static int ipfw_divert(struct mbuf **, int, int);
int
ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ip_fw_args args;
struct m_tag *dn_tag;
@ -102,6 +103,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
again:
args.m = *m0;
args.inp = inp;
ipfw = ipfw_chk(&args);
*m0 = args.m;
@ -156,7 +158,8 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
}
int
ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ip_fw_args args;
struct m_tag *dn_tag;
@ -186,6 +189,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
again:
args.m = *m0;
args.oif = ifp;
args.inp = inp;
ipfw = ipfw_chk(&args);
*m0 = args.m;

View File

@ -437,7 +437,7 @@ ip_input(struct mbuf *m)
odst = ip->ip_dst;
if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif,
PFIL_IN) != 0)
PFIL_IN, NULL) != 0)
return;
if (m == NULL) /* consumed by filter */
return;

View File

@ -662,7 +662,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro,
/* Run through list of hooks for output packets. */
odst.s_addr = ip->ip_dst.s_addr;
error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT);
error = pfil_run_hooks(&inet_pfil_hook, &m, ifp, PFIL_OUT, inp);
if (error != 0 || m == NULL)
goto done;

View File

@ -580,7 +580,7 @@ ip6_forward(m, srcrt)
goto pass;
/* Run through list of hooks for output packets. */
error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT);
error = pfil_run_hooks(&inet6_pfil_hook, &m, rt->rt_ifp, PFIL_OUT, NULL);
if (error != 0)
goto senderr;
if (m == NULL)

View File

@ -424,7 +424,7 @@ ip6_input(m)
if (inet6_pfil_hook.ph_busy_count == -1)
goto passin;
if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN))
if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, PFIL_IN, NULL))
return;
if (m == NULL) /* consumed by filter */
return;

View File

@ -938,7 +938,7 @@ skip_ipsec2:;
goto passout;
/* Run through list of hooks for output packets. */
error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT);
error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT, inp);
if (error != 0 || m == NULL)
goto done;
ip6 = mtod(m, struct ip6_hdr *);

View File

@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 600003 /* Master, propagated to newvers */
#define __FreeBSD_version 600004 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>