Index: sys/netinet6/frag6.c =================================================================== --- sys/netinet6/frag6.c +++ sys/netinet6/frag6.c @@ -494,57 +494,13 @@ if (af6->ip6af_off > ip6af->ip6af_off) break; -#if 0 - /* - * If there is a preceding segment, it may provide some of - * our data already. If so, drop the data from the incoming - * segment. If it provides all of our data, drop us. - */ - if (af6 != NULL) - af6tmp = TAILQ_PREV(af6, ip6fraghead, ip6af_tq); - else - af6tmp = TAILQ_LAST(&q6->ip6q_frags, ip6fraghead); - if (af6tmp != NULL) { - i = af6tmp->ip6af_off + af6tmp->ip6af_frglen - - ip6af->ip6af_off; - if (i > 0) { - if (i >= ip6af->ip6af_frglen) - goto dropfrag; - m_adj(IP6_REASS_MBUF(ip6af), i); - ip6af->ip6af_off += i; - ip6af->ip6af_frglen -= i; - } - } - - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (af6 != NULL) { - i = (ip6af->ip6af_off + ip6af->ip6af_frglen) - af6->ip6af_off; - if (i <= 0) - break; - if (i < af6->ip6af_frglen) { - af6->ip6af_frglen -= i; - af6->ip6af_off += i; - m_adj(IP6_REASS_MBUF(af6), i); - break; - } - af6tmp = TAILQ_NEXT(af6, ip6af_tq); - m_freem(IP6_REASS_MBUF(af6)); - TAILQ_REMOVE(&q6->ip6q_frags, af6, ip6af_tq); - af6 = af6tmp; - } -#else /* * If the incoming framgent overlaps some existing fragments in - * the reassembly queue, drop it, since it is dangerous to override - * existing fragments from a security point of view. - * We don't know which fragment is the bad guy - here we trust - * fragment that came in earlier, with no real reason. - * - * Note: due to changes after disabling this part, mbuf passed to - * m_adj() below now does not meet the requirement. + * the reassembly queue, drop both the new fragment and the + * entire reassembly queue. However, if the new fragment + * is an exact duplicate of an existing fragment, only silently + * drop the existing fragment and leave the fragmentation queue + * unchanged, as allowed by the RFC. (RFC 8200, 4.5) */ if (af6 != NULL) af6tmp = TAILQ_PREV(af6, ip6fraghead, ip6af_tq); @@ -560,6 +516,9 @@ i, ip6_sprintf(ip6buf, &q6->ip6q_src)); #endif free(ip6af, M_FTABLE); + if (af6tmp->ip6af_off != ip6af->ip6af_off || + af6tmp->ip6af_frglen != ip6af->ip6af_frglen) + frag6_freef(q6, hash); goto dropfrag; } } @@ -572,10 +531,12 @@ i, ip6_sprintf(ip6buf, &q6->ip6q_src)); #endif free(ip6af, M_FTABLE); + if (af6->ip6af_off != ip6af->ip6af_off || + af6->ip6af_frglen != ip6af->ip6af_frglen) + frag6_freef(q6, hash); goto dropfrag; } } -#endif insert: #ifdef MAC