svn commit: r347125 - stable/12/sys/netinet6
Michael Tuexen
tuexen at FreeBSD.org
Sat May 4 13:55:53 UTC 2019
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;
}
More information about the svn-src-stable-12
mailing list