Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2019 08:50:25 +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-11@freebsd.org
Subject:   svn commit: r347660 - stable/11/sys/netinet
Message-ID:  <201905160850.x4G8oPW7023880@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu May 16 08:50:25 2019
New Revision: 347660
URL: https://svnweb.freebsd.org/changeset/base/347660

Log:
  MFC r344048:
  
  Improve input validation for raw IPv4 socket using the IP_HDRINCL
  option.
  
  This issue was found by running syzkaller on OpenBSD.
  Greg Steuck made me aware that the problem might also exist on FreeBSD.

Modified:
  stable/11/sys/netinet/raw_ip.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/raw_ip.c
==============================================================================
--- stable/11/sys/netinet/raw_ip.c	Thu May 16 08:47:28 2019	(r347659)
+++ stable/11/sys/netinet/raw_ip.c	Thu May 16 08:50:25 2019	(r347660)
@@ -439,6 +439,8 @@ rip_output(struct mbuf *m, struct socket *so, ...)
 	u_long dst;
 	int flags = ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0) |
 	    IP_ALLOWBROADCAST;
+	int cnt;
+	u_char opttype, optlen, *cp;
 
 	va_start(ap, so);
 	dst = va_arg(ap, u_long);
@@ -512,6 +514,34 @@ rip_output(struct mbuf *m, struct socket *so, ...)
 			INP_RUNLOCK(inp);
 			m_freem(m);
 			return (EINVAL);
+		}
+		/*
+		 * Don't allow IP options which do not have the required
+		 * structure as specified in section 3.1 of RFC 791 on
+		 * pages 15-23.
+		 */
+		cp = (u_char *)(ip + 1);
+		cnt = (ip->ip_hl << 2) - sizeof (struct ip);
+		for (; cnt > 0; cnt -= optlen, cp += optlen) {
+			opttype = cp[IPOPT_OPTVAL];
+			if (opttype == IPOPT_EOL)
+				break;
+			if (opttype == IPOPT_NOP) {
+				optlen = 1;
+				continue;
+			}
+			if (cnt < IPOPT_OLEN + sizeof(u_char)) {
+				INP_RUNLOCK(inp);
+				m_freem(m);
+				return (EINVAL);
+			}
+			optlen = cp[IPOPT_OLEN];
+			if (optlen < IPOPT_OLEN + sizeof(u_char) ||
+			    optlen > cnt) {
+				INP_RUNLOCK(inp);
+				m_freem(m);
+				return (EINVAL);
+			}
 		}
 		/*
 		 * This doesn't allow application to specify ID of zero,



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