pf_map_addr() can fail and in this case we should drop the packet,
otherwise bad consequences including a routing loop can occur. Move pf_set_rt_ifp() earlier in state creation sequence and inline it, cutting some extra code. PR: 183997 Submitted by: Kajetan Staszkiewicz <vegeta tuxpowered.net> Sponsored by: InnoGames GmbH
This commit is contained in:
parent
d8e198e6b4
commit
afab0f7e01
@ -266,8 +266,6 @@ static u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
|
||||
sa_family_t);
|
||||
static u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
|
||||
int, u_int16_t);
|
||||
static void pf_set_rt_ifp(struct pf_state *,
|
||||
struct pf_addr *);
|
||||
static int pf_check_proto_cksum(struct mbuf *, int, int,
|
||||
u_int8_t, sa_family_t);
|
||||
static void pf_print_state_parts(struct pf_state *,
|
||||
@ -2957,31 +2955,6 @@ pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
|
||||
return (mss);
|
||||
}
|
||||
|
||||
static void
|
||||
pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
|
||||
{
|
||||
struct pf_rule *r = s->rule.ptr;
|
||||
struct pf_src_node *sn = NULL;
|
||||
|
||||
s->rt_kif = NULL;
|
||||
if (!r->rt || r->rt == PF_FASTROUTE)
|
||||
return;
|
||||
switch (s->key[PF_SK_WIRE]->af) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn);
|
||||
s->rt_kif = r->rpool.cur->kif;
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn);
|
||||
s->rt_kif = r->rpool.cur->kif;
|
||||
break;
|
||||
#endif /* INET6 */
|
||||
}
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
pf_tcp_iss(struct pf_pdesc *pd)
|
||||
{
|
||||
@ -3544,6 +3517,19 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
|
||||
s->timeout = PFTM_OTHER_FIRST_PACKET;
|
||||
}
|
||||
|
||||
if (r->rt && r->rt != PF_FASTROUTE) {
|
||||
struct pf_src_node *sn = NULL;
|
||||
|
||||
if (pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL, &sn)) {
|
||||
REASON_SET(&reason, PFRES_MAPFAILED);
|
||||
pf_src_tree_remove_state(s);
|
||||
STATE_DEC_COUNTERS(s);
|
||||
uma_zfree(V_pf_state_z, s);
|
||||
goto csfailed;
|
||||
}
|
||||
s->rt_kif = r->rpool.cur->kif;
|
||||
}
|
||||
|
||||
s->creation = time_uptime;
|
||||
s->expire = time_uptime;
|
||||
|
||||
@ -3609,7 +3595,6 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
|
||||
} else
|
||||
*sm = s;
|
||||
|
||||
pf_set_rt_ifp(s, pd->src); /* needs s->state_key set */
|
||||
if (tag > 0)
|
||||
s->tag = tag;
|
||||
if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
|
||||
|
@ -124,7 +124,8 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
|
||||
#define PFRES_MAXSTATES 12 /* State limit */
|
||||
#define PFRES_SRCLIMIT 13 /* Source node/conn limit */
|
||||
#define PFRES_SYNPROXY 14 /* SYN proxy */
|
||||
#define PFRES_MAX 15 /* total+1 */
|
||||
#define PFRES_MAPFAILED 15 /* pf_map_addr() failed */
|
||||
#define PFRES_MAX 16 /* total+1 */
|
||||
|
||||
#define PFRES_NAMES { \
|
||||
"match", \
|
||||
@ -142,6 +143,7 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
|
||||
"state-limit", \
|
||||
"src-limit", \
|
||||
"synproxy", \
|
||||
"map-failed", \
|
||||
NULL \
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user