NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
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
>Number: 50766
>Category: kern
>Synopsis: panic in tcp_input.c on the banana pi (earm7hf) when trying to connect an ipv6 address through a gif ipv6 in ipv4 tunnel
>Confidential: no
>Severity: non-critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 03 23:40:00 +0000 2016
>Originator: Zafer Aydogan
>Release: 7.0
>Organization:
>Environment:
NetBSD bpi 7.0.0_PATCH NetBSD 7.0.0_PATCH (BPI) #2: Wed Feb 3 22:33:20 UTC 2016 zafer@current:/data/objdir/sys/arch/evbarm/compile/BPI evbarm
>Description:
With a banana pi running NetBSD 7.0 following panic occurs when trying to connect to an ipv6 address through a gif ipv6 in ipv4 tunnel
panic: kernel diagnostic assertion "TCP_HDR_ALIGNED_P(th) failed: file /data/src/sys/netinet/tcp_input.c line 1344.
ping6 and traceroute6 on the other hand are working just fine. Panic happens only upon connect.
Also, I cross-checked this issue on amd64, where it does not appear.
You can connect just fine on amd64.
>How-To-Repeat:
Please enable pseudo device gif in the BPI kernel first,
then create a tunnel to an ipv6 enabled server.
I am using this script:
#!/bin/sh
ifconfig gif0 create
ifconfig gif0 tunnel 192.168.0.216 104.207.131.231
ifconfig gif0 inet6 2001:19f0:6c00:9089:8487:979e:c000:2 2001:19f0:6c00:9089:8487:979e:c000:1 prefixlen 128
route -n add -inet6 default 2001:19f0:6c00:9089:8487:979e:c000:1
where c000:2 and c000:1 are endpoints. 1 is the ipv6 enabled server and 2 is the banana pi at home. both endpoints are running NetBSD 7.0. The server is amd64.
I have applied following patches that show that nothing was misaligned prior to IP6_EXTHDR_GET in tcp_input.c on line 1298
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index 61a09aa..a4ed39e 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -57,6 +57,10 @@ __KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.64 2014/05/18 14:46:16 rmind Exp $");
#include <netinet/in_var.h>
#include <netinet/ip_encap.h>
#include <netinet/ip_ecn.h>
+#include <netinet/ip_private.h>
+#include <netinet/tcp_private.h>
+#include <netinet/udp_private.h>
+#include <netinet6/ip6_private.h>
#ifdef INET6
#include <netinet/ip6.h>
@@ -211,6 +215,11 @@ in_gif_input(struct mbuf *m, ...)
proto = va_arg(ap, int);
va_end(ap);
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(IP_HDR_ALIGNED_P(off));
+ KASSERT(IP6_HDR_ALIGNED_P(off));
+ KASSERT(TCP_HDR_ALIGNED_P(off));
+ KASSERT(UDP_HDR_ALIGNED_P(off));
ip = mtod(m, const struct ip *);
gifp = (struct ifnet *)encap_getarg(m);
@@ -230,6 +239,7 @@ in_gif_input(struct mbuf *m, ...)
otos = ip->ip_tos;
m_adj(m, off);
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
switch (proto) {
#ifdef INET
@@ -241,6 +251,7 @@ in_gif_input(struct mbuf *m, ...)
if ((m = m_pullup(m, sizeof(*xip))) == NULL)
return;
}
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
xip = mtod(m, struct ip *);
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos, &xip->ip_tos);
@@ -259,6 +270,7 @@ in_gif_input(struct mbuf *m, ...)
if ((m = m_pullup(m, sizeof(*ip6))) == NULL)
return;
}
+ KASSERT(IP6_HDR_ALIGNED_P(mtod(m, void *)));
ip6 = mtod(m, struct ip6_hdr *);
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
if (gifp->if_flags & IFF_LINK1)
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index cb80d94..7295941 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -407,12 +407,14 @@ ip_input(struct mbuf *m)
return;
}
}
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
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;
@@ -422,6 +424,7 @@ ip_input(struct mbuf *m)
IP_STATINC(IP_STAT_BADHLEN);
return;
}
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
ip = mtod(m, struct ip *);
}
@@ -526,8 +529,10 @@ ip_input(struct mbuf *m)
if (freed || m == NULL) {
return;
}
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+ KASSERT(IP_HDR_ALIGNED_P(hlen));
/*
* XXX The setting of "srcrt" here is to prevent ip_forward()
@@ -736,8 +741,10 @@ ours:
* Reassembly is done, we have the final packet.
* Updated cached data in local variable(s).
*/
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+ KASSERT(IP_HDR_ALIGNED_P(hlen));
}
#ifdef IPSEC
@@ -768,6 +775,9 @@ ours:
const int off = hlen, nh = ip->ip_p;
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(IP_HDR_ALIGNED_P(off));
+
SOFTNET_LOCK();
(*inetsw[ip_protox[nh]].pr_input)(m, off, nh);
SOFTNET_UNLOCK();
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 4362c99..88857227 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -212,6 +212,7 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.334.2.2 2015/07/24 07:30:40 martin E
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcp_private.h>
+#include <netinet/ip_private.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_congctl.h>
#include <netinet/tcp_debug.h>
@@ -1237,6 +1238,11 @@ tcp_input(struct mbuf *m, ...)
(void)va_arg(ap, int); /* ignore value, advance ap */
va_end(ap);
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(IP_HDR_ALIGNED_P(toff));
+ KASSERT(TCP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(TCP_HDR_ALIGNED_P(toff));
+
TCP_STATINC(TCP_STAT_RCVTOTAL);
memset(&opti, 0, sizeof(opti));
@@ -1267,6 +1273,7 @@ tcp_input(struct mbuf *m, ...)
* Get IP and TCP header.
* Note: IP leaves IP header in first mbuf.
*/
+ KASSERT(IP_HDR_ALIGNED_P(mtod(m, void *)));
ip = mtod(m, struct ip *);
switch (ip->ip_v) {
#ifdef INET
@@ -1276,12 +1283,15 @@ tcp_input(struct mbuf *m, ...)
#endif
af = AF_INET;
iphlen = sizeof(struct ip);
+ KASSERT(TCP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(TCP_HDR_ALIGNED_P(toff));
IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
sizeof(struct tcphdr));
if (th == NULL) {
TCP_STATINC(TCP_STAT_RCVSHORT);
return;
}
+ KASSERT(TCP_HDR_ALIGNED_P(th));
/* We do the checksum after PCB lookup... */
len = ntohs(ip->ip_len);
tlen = len - toff;
@@ -1294,12 +1304,15 @@ tcp_input(struct mbuf *m, ...)
iphlen = sizeof(struct ip6_hdr);
af = AF_INET6;
ip6 = mtod(m, struct ip6_hdr *);
+ KASSERT(TCP_HDR_ALIGNED_P(mtod(m, void *)));
+ KASSERT(TCP_HDR_ALIGNED_P(toff));
IP6_EXTHDR_GET(th, struct tcphdr *, m, toff,
sizeof(struct tcphdr));
if (th == NULL) {
TCP_STATINC(TCP_STAT_RCVSHORT);
return;
}
+ KASSERT(TCP_HDR_ALIGNED_P(th));
/* Be proactive about malicious use of IPv4 mapped address */
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
>Fix:
Home |
Main Index |
Thread Index |
Old Index