svn commit: r344048 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Tue Feb 12 10:17:22 UTC 2019
Author: tuexen
Date: Tue Feb 12 10:17:21 2019
New Revision: 344048
URL: https://svnweb.freebsd.org/changeset/base/344048
Log:
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.
Reported by: Greg Steuck
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D18834
Modified:
head/sys/netinet/raw_ip.c
Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c Tue Feb 12 09:26:05 2019 (r344047)
+++ head/sys/netinet/raw_ip.c Tue Feb 12 10:17:21 2019 (r344048)
@@ -454,6 +454,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);
@@ -527,6 +529,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,
More information about the svn-src-all
mailing list