NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/50766: panic in tcp_input.c on the banana pi (earm7hf) when trying to connect an ipv6 address through a gif ipv6 in ipv4 tunnel



I reproduced this on my bpi with

and got


panic: kernel diagnostic assertion "TCP_HDR_ALIGNED_P(th)" failed: file "/wrk/bpi/src/sys/netinet/tcp_input.c", line 1358
Stopped in pid 0.3 (system) at  netbsd:cpu_Debugger+0x4: bx      r14
db{0}> t
0xbfee7d04: netbsd:vpanic+0xc
0xbfee7d1c: netbsd:__udivmoddi4
0xbfee7e8c: netbsd:tcp_input+0x2d14
0xbfee7ecc: netbsd:tcp6_input+0x11c
0xbfee7f4c: netbsd:ip6_input+0x9f4
0xbfee7f64: netbsd:ip6intr+0x74
0xbfee7fac: netbsd:softint_dispatch+0xd4
Bad frame pointer: 0xbf227e84
db{0}>


or

http://nxr.netbsd.org/xref/src/sys/netinet/tcp_input.c#1345

with HEAD

Nick
Index: sys/netinet/in_gif.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/in_gif.c,v
retrieving revision 1.75
diff -u -p -r1.75 in_gif.c
--- sys/netinet/in_gif.c	26 Jan 2016 06:00:10 -0000	1.75
+++ sys/netinet/in_gif.c	10 Feb 2016 10:10:02 -0000
@@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/ip_private.h>
 #include <netinet/ip_var.h>
 #include <netinet/in_gif.h>
 #include <netinet/in_var.h>
@@ -200,6 +201,8 @@ in_gif_input(struct mbuf *m, int off, in
 	int af;
 	u_int8_t otos;
 
+	ip_mbuf_align_check(m);
+	KASSERT(IP_HDR_ALIGNED_P(off));
 	ip = mtod(m, const struct ip *);
 
 	gifp = (struct ifnet *)encap_getarg(m);
@@ -226,6 +229,7 @@ in_gif_input(struct mbuf *m, int off, in
 #endif
 	otos = ip->ip_tos;
 	m_adj(m, off);
+	ip_mbuf_align_check(m);
 
 	switch (proto) {
 #ifdef INET
@@ -237,6 +241,7 @@ in_gif_input(struct mbuf *m, int off, in
 			if ((m = m_pullup(m, sizeof(*xip))) == NULL)
 				return;
 		}
+		ip_mbuf_align_check(m);
 		xip = mtod(m, struct ip *);
 		if (gifp->if_flags & IFF_LINK1)
 			ip_ecn_egress(ECN_ALLOWED, &otos, &xip->ip_tos);
@@ -255,6 +260,7 @@ in_gif_input(struct mbuf *m, int off, in
 			if ((m = m_pullup(m, sizeof(*ip6))) == NULL)
 				return;
 		}
+		ip_mbuf_align_check(m);
 		ip6 = mtod(m, struct ip6_hdr *);
 		itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
 		if (gifp->if_flags & IFF_LINK1)
@@ -271,6 +277,7 @@ in_gif_input(struct mbuf *m, int off, in
 		m_freem(m);
 		return;
 	}
+	ip_mbuf_align_check(m);
 	gif_input(m, af, gifp);
 	return;
 }
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_input.c,v
retrieving revision 1.328
diff -u -p -r1.328 ip_input.c
--- sys/netinet/ip_input.c	21 Jan 2016 15:41:30 -0000	1.328
+++ sys/netinet/ip_input.c	10 Feb 2016 10:10:02 -0000
@@ -411,12 +411,14 @@ ip_input(struct mbuf *m)
 			return;
 		}
 	}
+	ip_mbuf_align_check(m);
 	ip = mtod(m, struct ip *);
 	if (ip->ip_v != IPVERSION) {
 		IP_STATINC(IP_STAT_BADVERS);
 		goto bad;
 	}
 	hlen = ip->ip_hl << 2;
+	KASSERT(IP_HDR_ALIGNED_P(hlen));
 	if (hlen < sizeof(struct ip)) {	/* minimum header length */
 		IP_STATINC(IP_STAT_BADHLEN);
 		goto bad;
@@ -426,6 +428,7 @@ ip_input(struct mbuf *m)
 			IP_STATINC(IP_STAT_BADHLEN);
 			return;
 		}
+		ip_mbuf_align_check(m);
 		ip = mtod(m, struct ip *);
 	}
 
@@ -530,6 +533,7 @@ ip_input(struct mbuf *m)
 		if (freed || m == NULL) {
 			return;
 		}
+		ip_mbuf_align_check(m);
 		ip = mtod(m, struct ip *);
 		hlen = ip->ip_hl << 2;
 
@@ -744,6 +748,7 @@ ours:
 		 * Reassembly is done, we have the final packet.
 		 * Updated cached data in local variable(s).
 		 */
+		ip_mbuf_align_check(m);
 		ip = mtod(m, struct ip *);
 		hlen = ip->ip_hl << 2;
 	}
@@ -775,6 +780,8 @@ ours:
 	IP_STATINC(IP_STAT_DELIVERED);
 
 	const int off = hlen, nh = ip->ip_p;
+	KASSERT(IP_HDR_ALIGNED_P(off));
+	ip_mbuf_align_check(m);
 
 	SOFTNET_LOCK();
 	(*inetsw[ip_protox[nh]].pr_input)(m, off, nh);
Index: sys/netinet/ip_private.h
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_private.h,v
retrieving revision 1.3
diff -u -p -r1.3 ip_private.h
--- sys/netinet/ip_private.h	28 Apr 2008 20:24:09 -0000	1.3
+++ sys/netinet/ip_private.h	10 Feb 2016 10:10:02 -0000
@@ -48,6 +48,20 @@ extern	percpu_t *ipstat_percpu;
 #else
 #define	IP_HDR_ALIGNED_P(ip)	((((vaddr_t) (ip)) & 3) == 0)
 #endif
+
+#include <sys/mbuf.h>
+
+static inline void
+ip_mbuf_align_check(struct mbuf *m)
+{
+	unsigned i;
+
+	for (i = 0; m != NULL; m = m->m_next, i++) {
+		if (!IP_HDR_ALIGNED_P(m->m_data)) {
+		    printf("mbuf chunk %u misaligned: %p\n", i, m->m_data);
+		}
+	}
+}
 #endif /* _KERNEL */
 
 #endif /* !_NETINET_IP_PRIVATE_H_ */
Index: sys/netinet/tcp_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v
retrieving revision 1.344
diff -u -p -r1.344 tcp_input.c
--- sys/netinet/tcp_input.c	24 Aug 2015 22:21:26 -0000	1.344
+++ sys/netinet/tcp_input.c	10 Feb 2016 10:10:09 -0000
@@ -181,6 +181,7 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_input.c,
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/ip_private.h>
 #include <netinet/in_pcb.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_var.h>
@@ -820,6 +821,9 @@ tcp6_input(struct mbuf **mp, int *offp, 
 {
 	struct mbuf *m = *mp;
 
+	ip_mbuf_align_check(m);
+	KASSERT(IP_HDR_ALIGNED_P(*offp));
+
 	/*
 	 * draft-itojun-ipv6-tcp-to-anycast
 	 * better place to put this in?
@@ -832,6 +836,7 @@ tcp6_input(struct mbuf **mp, int *offp, 
 				return IPPROTO_DONE;
 			}
 		}
+		ip_mbuf_align_check(m);
 		ip6 = mtod(m, struct ip6_hdr *);
 		icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR,
 		    (char *)&ip6->ip6_dst - (char *)ip6);
@@ -1238,6 +1243,9 @@ tcp_input(struct mbuf *m, ...)
 	(void)va_arg(ap, int);		/* ignore value, advance ap */
 	va_end(ap);
 
+	ip_mbuf_align_check(m);
+	KASSERT(IP_HDR_ALIGNED_P(toff));
+
 	TCP_STATINC(TCP_STAT_RCVTOTAL);
 
 	memset(&opti, 0, sizeof(opti));
@@ -1268,6 +1276,7 @@ tcp_input(struct mbuf *m, ...)
 	 * Get IP and TCP header.
 	 * Note: IP leaves IP header in first mbuf.
 	 */
+	ip_mbuf_align_check(m);
 	ip = mtod(m, struct ip *);
 	switch (ip->ip_v) {
 #ifdef INET
@@ -1283,6 +1292,8 @@ tcp_input(struct mbuf *m, ...)
 			TCP_STATINC(TCP_STAT_RCVSHORT);
 			return;
 		}
+		ip_mbuf_align_check(m);
+		KASSERT(IP_HDR_ALIGNED_P(toff));
 		/* We do the checksum after PCB lookup... */
 		len = ntohs(ip->ip_len);
 		tlen = len - toff;
@@ -1301,6 +1312,8 @@ tcp_input(struct mbuf *m, ...)
 			TCP_STATINC(TCP_STAT_RCVSHORT);
 			return;
 		}
+		ip_mbuf_align_check(m);
+		KASSERT(IP_HDR_ALIGNED_P(toff));
 
 		/* Be proactive about malicious use of IPv4 mapped address */
 		if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.155
diff -u -p -r1.155 ip6_input.c
--- sys/netinet6/ip6_input.c	4 Feb 2016 02:48:37 -0000	1.155
+++ sys/netinet6/ip6_input.c	10 Feb 2016 10:10:12 -0000
@@ -106,6 +106,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,
 #include <netinet/portalgo.h>
 #include <netinet6/in6_var.h>
 #include <netinet6/ip6_var.h>
+#include <netinet/ip_private.h>
 #include <netinet6/ip6_private.h>
 #include <netinet6/in6_pcb.h>
 #include <netinet/icmp6.h>
@@ -308,6 +309,7 @@ ip6_input(struct mbuf *m)
 		}
 	}
 
+	ip_mbuf_align_check(m);
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
@@ -347,6 +349,7 @@ ip6_input(struct mbuf *m)
 			return;
 		if (m == NULL)
 			return;
+		ip_mbuf_align_check(m);
 		ip6 = mtod(m, struct ip6_hdr *);
 		srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst);
 	}
@@ -419,6 +422,7 @@ ip6_input(struct mbuf *m)
 	if (__predict_false(
 	    m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT)))
 		goto bad;
+	ip_mbuf_align_check(m);
 	ip6 = mtod(m, struct ip6_hdr *);
 	if (in6_clearscope(&ip6->ip6_src) || in6_clearscope(&ip6->ip6_dst)) {
 		IP6_STATINC(IP6_STAT_BADSCOPE);	/* XXX */
@@ -597,6 +601,7 @@ ip6_input(struct mbuf *m)
 		}
 
 		/* adjust pointer */
+		ip_mbuf_align_check(m);
 		ip6 = mtod(m, struct ip6_hdr *);
 
 		/*
@@ -681,6 +686,7 @@ ip6_input(struct mbuf *m)
 		return;
 	}
 
+	ip_mbuf_align_check(m);
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	/*
@@ -757,7 +763,11 @@ ip6_input(struct mbuf *m)
 		}
 #endif /* IPSEC */
 
+		ip_mbuf_align_check(m);
+		KASSERT(IP_HDR_ALIGNED_P(off));
 		nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
+		ip_mbuf_align_check(m);
+		KASSERT(IP_HDR_ALIGNED_P(off));
 	}
 	return;
  bad:


Home | Main Index | Thread Index | Old Index