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