Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 May 2019 13:55:52 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r347125 - stable/12/sys/netinet6
Message-ID:  <201905041355.x44Dtq8p020770@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sat May  4 13:55:51 2019
New Revision: 347125
URL: https://svnweb.freebsd.org/changeset/base/347125

Log:
  MFC r346400:
  Improve input validation for the socket option IPV6_CHECKSUM.
  
  When using the IPPROTO_IPV6 level socket option IPV6_CHECKSUM on a raw
  IPv6 socket, ensure that the value is either -1 or a non-negative even
  number.
  
  MFC r346401:
  Avoid a buffer overwrite in rip6_output() when computing the checksum
  as requested by the user via the IPPROTO_IPV6 level socket option
  IPV6_CHECKSUM. The check if there are enough bytes in the packet to
  store the checksum at the requested offset was wrong by 1.
  
  MFC r346402:
  When a checksum has to be computed for a received IPv6 packet because it
  is requested by the application using the IPPROTO_IPV6 level socket option
  IPV6_CHECKSUM on a raw socket, ensure that the packet contains enough
  bytes to contain the checksum at the specified offset.
  
  MFC r346406:
  When an IPv6 packet is received for a raw socket which has the
  IPPROTO_IPV6 level socket option IPV6_CHECKSUM enabled and the
  checksum check fails, drop the message. Without this fix, an
  ICMP6 message was sent indicating a parameter problem.
  
  Thanks to bz@ for suggesting a way to simplify this fix.
  
  Reviewed by:		bz@
  Sponsored by:		Netflix, Inc.
  Differential Revision:	https://reviews.freebsd.org/D19966
  Differential Revision:  https://reviews.freebsd.org/D19967
  Differential Revision:  https://reviews.freebsd.org/D19968
  Differential Revision:  https://reviews.freebsd.org/D19969

Modified:
  stable/12/sys/netinet6/ip6_output.c
  stable/12/sys/netinet6/raw_ip6.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet6/ip6_output.c
==============================================================================
--- stable/12/sys/netinet6/ip6_output.c	Sat May  4 13:43:48 2019	(r347124)
+++ stable/12/sys/netinet6/ip6_output.c	Sat May  4 13:55:51 2019	(r347125)
@@ -2216,8 +2216,11 @@ ip6_raw_ctloutput(struct socket *so, struct sockopt *s
 					    sizeof(optval));
 			if (error)
 				break;
-			if ((optval % 2) != 0) {
-				/* the API assumes even offset values */
+			if (optval < -1 || (optval % 2) != 0) {
+				/*
+				 * The API assumes non-negative even offset
+				 * values or -1 as a special value.
+				 */
 				error = EINVAL;
 			} else if (so->so_proto->pr_protocol ==
 			    IPPROTO_ICMPV6) {

Modified: stable/12/sys/netinet6/raw_ip6.c
==============================================================================
--- stable/12/sys/netinet6/raw_ip6.c	Sat May  4 13:43:48 2019	(r347124)
+++ stable/12/sys/netinet6/raw_ip6.c	Sat May  4 13:55:51 2019	(r347125)
@@ -239,9 +239,16 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
 		}
 		if (in6p->in6p_cksum != -1) {
 			RIP6STAT_INC(rip6s_isum);
-			if (in6_cksum(m, proto, *offp,
+			if (m->m_pkthdr.len - (*offp + in6p->in6p_cksum) < 2 ||
+			    in6_cksum(m, proto, *offp,
 			    m->m_pkthdr.len - *offp)) {
 				RIP6STAT_INC(rip6s_badsum);
+				/*
+				 * Drop the received message, don't send an
+				 * ICMP6 message. Set proto to IPPROTO_NONE
+				 * to achieve that.
+				 */
+				proto = IPPROTO_NONE;
 				goto skip_2;
 			}
 		}
@@ -495,7 +502,7 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
 			off = offsetof(struct icmp6_hdr, icmp6_cksum);
 		else
 			off = in6p->in6p_cksum;
-		if (plen < off + 1) {
+		if (plen < off + 2) {
 			error = EINVAL;
 			goto bad;
 		}



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