svn commit: r337801 - stable/11/sys/netinet6

Jonathan T. Looney jtl at FreeBSD.org
Tue Aug 14 18:12:03 UTC 2018


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


More information about the svn-src-all mailing list