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) MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D17594
This commit is contained in:
parent
8883128b8e
commit
1ff6e7a8a8
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user