From bc74b819918a5429f833804646cde1f72d398ab8 Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Tue, 12 May 2020 17:18:44 +0000 Subject: [PATCH] IPv6: Fix a panic in the nd6 code with unmapped mbufs. If the neighbor entry for an IPv6 TCP session using unmapped mbufs times out, IPv6 will send an icmp6 dest. unreachable message. In doing this, it will try to do a software checksum on the reflected packet. If this is a TCP session using unmapped mbufs, then there will be a kernel panic. To fix this, just free packets with unmapped mbufs, rather than sending the icmp. Reviewed by: np, rrs Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D24821 --- sys/netinet6/nd6.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index e13b08ee32cf..57009fba5886 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -821,9 +821,27 @@ nd6_llinfo_timer(void *arg) clear_llinfo_pqueue(ln); } nd6_free(&ln, 0); - if (m != NULL) - icmp6_error2(m, ICMP6_DST_UNREACH, - ICMP6_DST_UNREACH_ADDR, 0, ifp); + if (m != NULL) { + struct mbuf *n = m; + + /* + * if there are any ummapped mbufs, we + * must free them, rather than using + * them for an ICMP, as they cannot be + * checksummed. + */ + while ((n = n->m_next) != NULL) { + if (n->m_flags & M_EXTPG) + break; + } + if (n != NULL) { + m_freem(m); + m = NULL; + } else { + icmp6_error2(m, ICMP6_DST_UNREACH, + ICMP6_DST_UNREACH_ADDR, 0, ifp); + } + } } break; case ND6_LLINFO_REACHABLE: