Author: jtl
Date: Tue Aug 14 18:12:02 2018
New Revision: 337801
URL: https://svnweb.freebsd.org/changeset/base/337801

Log:
  MFC r337784:
    Drop 0-byte IPv6 fragments.
  
    Currently, we process IPv6 fragments with 0 bytes of payload, add them
    to the reassembly queue, and do not recognize them as duplicating or
    overlapping with adjacent 0-byte fragments. An attacker can exploit this
    to create long fragment queues.
  
    There is no legitimate reason for a fragment with no payload. However,
    because IPv6 packets with an empty payload are acceptable, allow an
    "atomic" fragment with no payload.
  
  Approved by:  so
  Security:     FreeBSD-SA-18:10.ip
  Security:     CVE-2018-6923

Modified:
  stable/11/sys/netinet6/frag6.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet6/frag6.c
==============================================================================
--- stable/11/sys/netinet6/frag6.c      Tue Aug 14 18:11:06 2018        
(r337800)
+++ stable/11/sys/netinet6/frag6.c      Tue Aug 14 18:12:02 2018        
(r337801)
@@ -269,6 +269,16 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
                return (ip6f->ip6f_nxt);
        }
 
+       /* Get fragment length and discard 0-byte fragments. */
+       frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
+       if (frgpartlen == 0) {
+               icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
+                   offsetof(struct ip6_hdr, ip6_plen));
+               in6_ifstat_inc(dstifp, ifs6_reass_fail);
+               IP6STAT_INC(ip6s_fragdropped);
+               return IPPROTO_DONE;
+       }
+
        hashkeyp = hashkey;
        memcpy(hashkeyp, &ip6->ip6_src, sizeof(struct in6_addr));
        hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
@@ -365,7 +375,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
         * in size.
         * If it would exceed, discard the fragment and return an ICMP error.
         */
-       frgpartlen = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) - offset;
        if (q6->ip6q_unfrglen >= 0) {
                /* The 1st fragment has already arrived. */
                if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to