Thread (15 messages) 15 messages, 4 authors, 2006-10-03

Re: PROBLEM: kernel BUG at net/ipv6/ip6_output.c:718

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: 2006-09-01 07:06:07
Subsystem: networking [general], networking [ipv4/ipv6], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds

On Thu, Aug 31, 2006 at 05:12:43PM +0200, cagri coltekin wrote:
It took a while to find equipment for test environment, but now I
have a test environment that I can test.

Here is the result:

---------------------------------------------------------------------------
[17180051.768000] ip6_fragment: hlen = 0x818, len = 0x7ce, nexthdr=4
Thanks for the result.  It looks like something is screwed up with the
extension headers.  What version of bind are you using?

Please try the following patch instead to see if we can further isolate
the problem.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} [off-list ref]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4fb47a2..e5ba216 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -508,6 +508,10 @@ static int ip6_fragment(struct sk_buff *
 	dev = rt->u.dst.dev;
 	hlen = ip6_find_1stfragopt(skb, &prevhdr);
 	nexthdr = *prevhdr;
+	if (unlikely(hlen > skb->len)) {
+		printk(KERN_CRIT "ip6_fragment: hlen = 0x%x, len = 0x%x, nexthdr = %d\n", hlen, skb->len, skb->nh.ipv6h->nexthdr);
+		BUG();
+	}
 
 	mtu = dst_mtu(&rt->u.dst);
 	if (np && np->frag_size < mtu) {
@@ -1204,6 +1208,8 @@ int ip6_push_pending_frames(struct sock 
 	struct flowi *fl = &inet->cork.fl;
 	unsigned char proto = fl->proto;
 	int err = 0;
+	u8 *prevhdr;
+	unsigned int hlen;
 
 	if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
 		goto out;
@@ -1249,6 +1255,14 @@ int ip6_push_pending_frames(struct sock 
 
 	skb->dst = dst_clone(&rt->u.dst);
 	IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);	
+
+	hlen = ip6_find_1stfragopt(skb, &prevhdr);
+	if (unlikely(hlen > skb->len)) {
+		printk(KERN_CRIT "ip6_push: hlen = 0x%x, len = 0x%x, nexthdr1 = %d, nexthdr2 = %d, proto = %d\n", hlen, skb->len, skb->nh.ipv6h->nexthdr, *prevhdr, proto);
+		printk(KERN_CRIT "ip6_push: opt = 0x%x, flen = %d, nflen = %d\n", (unsigned int)opt, opt ? opt->opt_flen : 0, opt ? opt->opt_nflen : 0);
+		BUG();
+	}
+
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
 	if (err) {
 		if (err > 0)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help