mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-28 08:02:54 +00:00
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:
parent
48ac555d83
commit
d6a8d58875
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=135920
5
UPDATING
5
UPDATING
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user