diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-01-23 18:37:21 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2012-01-23 18:37:21 +0000 |
commit | bb4a1aa885fbcdfc1215753a65eff08602291cf5 (patch) | |
tree | acb8d2fd0f87ab733f468d76563809a3dde5c6ff | |
parent | 7f03c6135168029dc951e54895750e5651e1f96e (diff) |
Do not keep state when dropping overlapping IPv6 fragments in pf
and IPv6 stack.
ok sperreault@
-rw-r--r-- | sys/net/pf_norm.c | 35 | ||||
-rw-r--r-- | sys/netinet6/frag6.c | 22 |
2 files changed, 18 insertions, 39 deletions
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c index 345969c7a91..e0eb39fc449 100644 --- a/sys/net/pf_norm.c +++ b/sys/net/pf_norm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_norm.c,v 1.150 2012/01/15 22:55:35 bluhm Exp $ */ +/* $OpenBSD: pf_norm.c,v 1.151 2012/01/23 18:37:20 bluhm Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> @@ -326,15 +326,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, return (frag); } - if (TAILQ_EMPTY(&frag->fr_queue)) { - /* - * Overlapping IPv6 fragments have been detected. Do not - * reassemble packet but also drop future fragments. - * This will be done for this ident/src/dst combination - * until fragment queue timeout. - */ - goto drop_fragment; - } + KASSERT(!TAILQ_EMPTY(&frag->fr_queue)); /* Remember maximum fragment len for refragmentation */ if (frent->fe_len > frag->fr_maxlen) @@ -372,7 +364,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, u_int16_t precut; if (frag->fr_af == AF_INET6) - goto flush_fragentries; + goto free_fragment; precut = prev->fe_off + prev->fe_len - frent->fe_off; if (precut >= frent->fe_len) { @@ -391,7 +383,7 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, u_int16_t aftercut; if (frag->fr_af == AF_INET6) - goto flush_fragentries; + goto free_fragment; aftercut = frent->fe_off + frent->fe_len - after->fe_off; if (aftercut < after->fe_len) { @@ -419,22 +411,15 @@ pf_fillup_fragment(struct pf_fragment_cmp *key, struct pf_frent *frent, return (frag); - flush_fragentries: + free_fragment: /* - * RFC5722: When reassembling an IPv6 datagram, if one or - * more its constituent fragments is determined to be an - * overlapping fragment, the entire datagram (and any constituent - * fragments, including those not yet received) MUST be - * silently discarded. + * RFC 5722, Errata 3089: When reassembling an IPv6 datagram, if one + * or more its constituent fragments is determined to be an overlapping + * fragment, the entire datagram (and any constituent fragments) MUST + * be silently discarded. */ DPFPRINTF(LOG_NOTICE, "flush overlapping fragments"); - while ((prev = TAILQ_FIRST(&frag->fr_queue)) != NULL) { - TAILQ_REMOVE(&frag->fr_queue, prev, fr_next); - - m_freem(prev->fe_m); - pool_put(&pf_frent_pl, prev); - pf_nfrents--; - } + pf_free_fragment(frag); bad_fragment: REASON_SET(reason, PFRES_FRAG); drop_fragment: diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 779740399ed..18ef0b035ec 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frag6.c,v 1.40 2012/01/10 17:09:02 bluhm Exp $ */ +/* $OpenBSD: frag6.c,v 1.41 2012/01/23 18:37:20 bluhm Exp $ */ /* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* @@ -285,14 +285,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto) q6->ip6q_dst = ip6->ip6_dst; q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */ q6->ip6q_nfrag = 0; - } else if (LIST_EMPTY(&q6->ip6q_asfrag)) { - /* - * Overlapping fragments have been detected. Do not - * reassemble packet but also drop future fragments. - * This will be done for this ident/src/dst combination - * until fragment queue timeout. - */ - goto dropfrag; } /* @@ -409,10 +401,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto) break; /* - * RFC5722: When reassembling an IPv6 datagram, if one or more its - * constituent fragments is determined to be an overlapping fragment, - * the entire datagram (and any constituent fragments, including those - * not yet received) MUST be silently discarded. + * RFC 5722, Errata 3089: When reassembling an IPv6 datagram, if one + * or more its constituent fragments is determined to be an overlapping + * fragment, the entire datagram (and any constituent fragments) MUST + * be silently discarded. */ if (paf6 != LIST_END(&q6->ip6q_asfrag)) { i = (paf6->ip6af_off + paf6->ip6af_frglen) - ip6af->ip6af_off; @@ -549,8 +541,10 @@ frag6_input(struct mbuf **mp, int *offp, int proto) free(af6, M_FTABLE); } ip6stat.ip6s_fragdropped += q6->ip6q_nfrag; + TAILQ_REMOVE(&frag6_queue, q6, ip6q_queue); frag6_nfrags -= q6->ip6q_nfrag; - q6->ip6q_nfrag = 0; + free(q6, M_FTABLE); + frag6_nfragpackets--; dropfrag: in6_ifstat_inc(dstifp, ifs6_reass_fail); |