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
The following reply was made to PR kern/50766; it has been noted by GNATS.
From: Nick Hudson <skrll%netbsd.org@localhost>
To: gnats-bugs%NetBSD.org@localhost, kern-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost
Cc:
Subject: 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
Date: Wed, 10 Feb 2016 10:11:42 +0000
This is a multi-part message in MIME format.
--------------000108030809020100050007
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 7bit
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
--------------000108030809020100050007
Content-Type: text/x-patch;
name="bpi.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="bpi.diff"
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:
--------------000108030809020100050007--
Home |
Main Index |
Thread Index |
Old Index