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);

Reply via email to