On Fri, Jan 13, 2012 at 11:44:20AM -0700, Theo de Raadt wrote:
> > I have to drop them all, "including those not yet received".
>
> That last bit is crazy. You cannot maintain state until the potential
> packets fall out of the fragment cache.
This is also true for the reassembly implementation in the IPv6 stack.
Let's fix that, too.
bluhm
ok?
Index: netinet6/frag6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/frag6.c,v
retrieving revision 1.40
diff -u -p -r1.40 frag6.c
--- netinet6/frag6.c 10 Jan 2012 17:09:02 -0000 1.40
+++ netinet6/frag6.c 13 Jan 2012 21:54:26 -0000
@@ -285,14 +285,6 @@ frag6_input(struct mbuf **mp, int *offp,
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;
}
/*
@@ -411,8 +403,8 @@ frag6_input(struct mbuf **mp, int *offp,
/*
* 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.
+ * 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,
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);