svn commit: r339950 - stable/12/sys/netinet6
Bjoern A. Zeeb
bz at FreeBSD.org
Wed Oct 31 12:49:19 UTC 2018
Author: bz
Date: Wed Oct 31 12:49:18 2018
New Revision: 339950
URL: https://svnweb.freebsd.org/changeset/base/339950
Log:
MFC r339682:
rip6_input() inp validation after epoch(9)
After r335924 rip6_input() needs inp validation to avoid
working on FREED inps.
Apply the relevant bits from r335497,r335501 (rip_input() change)
to the IPv6 counterpart.
PR: 232194
Reviewed by: rgrimes, ae (,hps)
Approved by: re (kib)
Modified:
stable/12/sys/netinet6/raw_ip6.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/netinet6/raw_ip6.c
==============================================================================
--- stable/12/sys/netinet6/raw_ip6.c Wed Oct 31 12:05:45 2018 (r339949)
+++ stable/12/sys/netinet6/raw_ip6.c Wed Oct 31 12:49:18 2018 (r339950)
@@ -187,6 +187,45 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) &&
!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src))
continue;
+ if (last != NULL) {
+ struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+
+#if defined(IPSEC) || defined(IPSEC_SUPPORT)
+ /*
+ * Check AH/ESP integrity.
+ */
+ if (IPSEC_ENABLED(ipv6)) {
+ if (n != NULL &&
+ IPSEC_CHECK_POLICY(ipv6, n, last) != 0) {
+ m_freem(n);
+ /* Do not inject data into pcb. */
+ n = NULL;
+ }
+ }
+#endif /* IPSEC */
+ if (n) {
+ if (last->inp_flags & INP_CONTROLOPTS ||
+ last->inp_socket->so_options & SO_TIMESTAMP)
+ ip6_savecontrol(last, n, &opts);
+ /* strip intermediate headers */
+ m_adj(n, *offp);
+ if (sbappendaddr(&last->inp_socket->so_rcv,
+ (struct sockaddr *)&fromsa,
+ n, opts) == 0) {
+ m_freem(n);
+ if (opts)
+ m_freem(opts);
+ RIP6STAT_INC(rip6s_fullsock);
+ } else
+ sorwakeup(last->inp_socket);
+ opts = NULL;
+ }
+ INP_RUNLOCK(last);
+ last = NULL;
+ }
+ INP_RLOCK(in6p);
+ if (__predict_false(in6p->inp_flags2 & INP_FREED))
+ goto skip_2;
if (jailed_without_vnet(in6p->inp_cred)) {
/*
* Allow raw socket in jail to receive multicast;
@@ -196,16 +235,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
prison_check_ip6(in6p->inp_cred,
&ip6->ip6_dst) != 0)
- continue;
+ goto skip_2;
}
- INP_RLOCK(in6p);
if (in6p->in6p_cksum != -1) {
RIP6STAT_INC(rip6s_isum);
if (in6_cksum(m, proto, *offp,
m->m_pkthdr.len - *offp)) {
- INP_RUNLOCK(in6p);
RIP6STAT_INC(rip6s_badsum);
- continue;
+ goto skip_2;
}
}
/*
@@ -251,46 +288,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
}
if (blocked != MCAST_PASS) {
IP6STAT_INC(ip6s_notmember);
- INP_RUNLOCK(in6p);
- continue;
+ goto skip_2;
}
}
- if (last != NULL) {
- struct mbuf *n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
-
-#if defined(IPSEC) || defined(IPSEC_SUPPORT)
- /*
- * Check AH/ESP integrity.
- */
- if (IPSEC_ENABLED(ipv6)) {
- if (n != NULL &&
- IPSEC_CHECK_POLICY(ipv6, n, last) != 0) {
- m_freem(n);
- /* Do not inject data into pcb. */
- n = NULL;
- }
- }
-#endif /* IPSEC */
- if (n) {
- if (last->inp_flags & INP_CONTROLOPTS ||
- last->inp_socket->so_options & SO_TIMESTAMP)
- ip6_savecontrol(last, n, &opts);
- /* strip intermediate headers */
- m_adj(n, *offp);
- if (sbappendaddr(&last->inp_socket->so_rcv,
- (struct sockaddr *)&fromsa,
- n, opts) == 0) {
- m_freem(n);
- if (opts)
- m_freem(opts);
- RIP6STAT_INC(rip6s_fullsock);
- } else
- sorwakeup(last->inp_socket);
- opts = NULL;
- }
- INP_RUNLOCK(last);
- }
last = in6p;
+ continue;
+skip_2:
+ INP_RUNLOCK(in6p);
}
INP_INFO_RUNLOCK_ET(&V_ripcbinfo, et);
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
More information about the svn-src-stable
mailing list