Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Aug 2018 17:29:22 +0000 (UTC)
From:      "Jonathan T. Looney" <jtl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r337784 - head/sys/netinet6
Message-ID:  <201808141729.w7EHTMMN017049@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jtl
Date: Tue Aug 14 17:29:22 2018
New Revision: 337784
URL: https://svnweb.freebsd.org/changeset/base/337784

Log:
  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.
  
  Reviewed by:	jhb
  Security:	FreeBSD-SA-18:10.ip
  Security:	CVE-2018-6923

Modified:
  head/sys/netinet6/frag6.c

Modified: head/sys/netinet6/frag6.c
==============================================================================
--- head/sys/netinet6/frag6.c	Tue Aug 14 17:27:41 2018	(r337783)
+++ head/sys/netinet6/frag6.c	Tue Aug 14 17:29:22 2018	(r337784)
@@ -271,6 +271,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);
@@ -368,7 +378,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?201808141729.w7EHTMMN017049>