Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Aug 2018 18:12:02 +0000 (UTC)
From:      "Jonathan T. Looney" <jtl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r337801 - stable/11/sys/netinet6
Message-ID:  <201808141812.w7EIC2i1042899@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808141812.w7EIC2i1042899>