Package: linux-image-2.6.18-6-mckinley
Version: 2.6.18.dfsg.1-24etch3

hi,

i've encountered a problem with BIND9 running on oldstable.  we're
running native IPv6 and serving DNSSEC-signed zones, so the problem
appears to be related to IPv6/UDP fragmentation.

when the problem manifests itself the named process stops serving DNS
requests and the process becomes unkillable.

i am fairly certain that this is the same bug:

    http://www.mail-archive.com/net...@vger.kernel.org/msg21249.html

in particular, see:

    http://www.mail-archive.com/net...@vger.kernel.org/msg23619.html

the bug fix (132a55f3c5c0b1a364d32f65595ad8838c30a60e) was merged to
2.6.19 but never added to 2.6.18.  it would probably be a good idea to
add this fix in an oldstable kernel update.

here is the BUG() dmesg output:

kernel BUG at net/ipv6/ip6_output.c:699!
named[1992]: bugcheck! 0 [1]
Modules linked in: button xt_tcpudp xt_state ip_conntrack nfnetlink 
iptable_filter 
ip_tables x_tables dm_snapshot dm_mirror dm_mod ipv6 loop shpchp pci_hotplug 
ext3 jbd 
mbcache ide_cd cdrom generic mptspi mptscsih ohci_hcd ehci_hcd mptbase cmd64x 
cciss 
scsi_transport_spi usbcore ide_core scsi_mod e1000 thermal processor fan

Pid: 1992, CPU 0, comm:                named
psr : 0000101008526030 ifs : 8000000000000916 ip  : [<a000000204195ee0>]    Not 
tainted
ip is at ip6_output+0x5e0/0x1400 [ipv6]
unat: 0000000000000000 pfs : 0000000000000916 rsc : 0000000000000003
rnat: 0000000000000000 bsps: 0000000000000000 pr  : 0000000000569959
ldrs: 0000000000000000 ccv : 0000000000000000 fpsr: 0009804c8a70033f
csd : 0000000000000000 ssd : 0000000000000000
b0  : a000000204195ee0 b6  : a0000001000b30a0 b7  : a000000100283c40
f6  : 1003e00000000000000a0 f7  : 1003e20c49ba5e353f7cf
f8  : 1003e00000000000004e2 f9  : 1003e000000000fa00000
f10 : 1003e000000003b9aca00 f11 : 1003e431bde82d7b634db
r1  : a0000001008db0e0 r2  : ffffffffffff41c8 r3  : a00000010068cf38
r8  : 000000000000002c r9  : 0000000000000000 r10 : a0000001006f3350
r11 : 0000000000004000 r12 : e0000040f9117aa0 r13 : e0000040f9110000
r14 : 0000000000004000 r15 : a00000010068cf38 r16 : a00000010068cf40
r17 : 0000000000004000 r18 : e0000040f9110fd4 r19 : 0000000000000000
r20 : 0000000000000000 r21 : 0000000000000000 r22 : 0000000000000004
r23 : 0000000000000000 r24 : e0000040f9110fd4 r25 : 0000000000000750
r26 : 0000000000000730 r27 : 0000000000000073 r28 : 0000000000000073
r29 : 000000000027ffd8 r30 : 00000027ffd80000 r31 : 00000000000027d8

Call Trace:
 [<a000000100012f20>] show_stack+0x40/0xa0
                                sp=e0000040f9117630 bsp=e0000040f9111608
 [<a000000100013820>] show_regs+0x840/0x880
                                sp=e0000040f9117800 bsp=e0000040f91115a8
 [<a000000100034420>] die+0x1c0/0x2c0
                                sp=e0000040f9117800 bsp=e0000040f9111560
 [<a000000100034570>] die_if_kernel+0x50/0x80
                                sp=e0000040f9117820 bsp=e0000040f9111530
 [<a000000100035cb0>] ia64_bad_break+0x270/0x4a0
                                sp=e0000040f9117820 bsp=e0000040f9111508
 [<a00000010000bc40>] ia64_leave_kernel+0x0/0x280
                                sp=e0000040f91178d0 bsp=e0000040f9111508
 [<a000000204195ee0>] ip6_output+0x5e0/0x1400 [ipv6]
                                sp=e0000040f9117aa0 bsp=e0000040f9111458
 [<a0000002041979c0>] ip6_push_pending_frames+0x940/0xb80 [ipv6]
                                sp=e0000040f9117ab0 bsp=e0000040f9111408
 [<a0000002041c59e0>] udp_v6_push_pending_frames+0x6a0/0x700 [ipv6]
                                sp=e0000040f9117ae0 bsp=e0000040f91113b8
 [<a0000002041c8ad0>] udpv6_sendmsg+0xed0/0x14a0 [ipv6]
                                sp=e0000040f9117ae0 bsp=e0000040f9111330
 [<a00000010047b810>] inet_sendmsg+0xd0/0x100
                                sp=e0000040f9117b60 bsp=e0000040f91112f8
 [<a0000001003add70>] sock_sendmsg+0x1f0/0x240
                                sp=e0000040f9117b60 bsp=e0000040f91112c0
 [<a0000001003b2960>] sys_sendmsg+0x4a0/0x5a0
                                sp=e0000040f9117cc0 bsp=e0000040f9111228
 [<a00000010000baa0>] ia64_ret_from_syscall+0x0/0x20
                                sp=e0000040f9117e30 bsp=e0000040f9111228
 [<a000000000010620>] __start_ivt_text+0xffffffff00010620/0x400
                                sp=e0000040f9118000 bsp=e0000040f9111228

-- 
Robert Edmonds
edmo...@debian.org
From 132a55f3c5c0b1a364d32f65595ad8838c30a60e Mon Sep 17 00:00:00 2001
From: Herbert Xu <herb...@gondor.apana.org.au>
Date: Tue, 3 Oct 2006 14:34:00 -0700
Subject: [PATCH] [UDP6]: Fix flowi clobbering

The udp6_sendmsg function uses a shared buffer to store the
flow without taking any locks.  This leads to races with SMP.
This patch moves the flowi object onto the stack.

Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>
Acked-by: James Morris <jmor...@namei.org>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv6/udp.c |   62 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 9662561..552ec0f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -546,7 +546,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 	struct in6_addr *daddr, *final_p = NULL, final;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
-	struct flowi *fl = &inet->cork.fl;
+	struct flowi fl;
 	struct dst_entry *dst;
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
@@ -626,19 +626,19 @@ do_udp_sendmsg:
 	}
 	ulen += sizeof(struct udphdr);
 
-	memset(fl, 0, sizeof(*fl));
+	memset(&fl, 0, sizeof(fl));
 
 	if (sin6) {
 		if (sin6->sin6_port == 0)
 			return -EINVAL;
 
-		fl->fl_ip_dport = sin6->sin6_port;
+		fl.fl_ip_dport = sin6->sin6_port;
 		daddr = &sin6->sin6_addr;
 
 		if (np->sndflow) {
-			fl->fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
-			if (fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
-				flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
 				if (flowlabel == NULL)
 					return -EINVAL;
 				daddr = &flowlabel->dst;
@@ -656,32 +656,32 @@ do_udp_sendmsg:
 		if (addr_len >= sizeof(struct sockaddr_in6) &&
 		    sin6->sin6_scope_id &&
 		    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
-			fl->oif = sin6->sin6_scope_id;
+			fl.oif = sin6->sin6_scope_id;
 	} else {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -EDESTADDRREQ;
 
-		fl->fl_ip_dport = inet->dport;
+		fl.fl_ip_dport = inet->dport;
 		daddr = &np->daddr;
-		fl->fl6_flowlabel = np->flow_label;
+		fl.fl6_flowlabel = np->flow_label;
 		connected = 1;
 	}
 
-	if (!fl->oif)
-		fl->oif = sk->sk_bound_dev_if;
+	if (!fl.oif)
+		fl.oif = sk->sk_bound_dev_if;
 
 	if (msg->msg_controllen) {
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 		opt->tot_len = sizeof(*opt);
 
-		err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass);
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit, &tclass);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
 		}
-		if ((fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
-			flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
+		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
 			if (flowlabel == NULL)
 				return -EINVAL;
 		}
@@ -695,39 +695,39 @@ do_udp_sendmsg:
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 	opt = ipv6_fixup_options(&opt_space, opt);
 
-	fl->proto = IPPROTO_UDP;
-	ipv6_addr_copy(&fl->fl6_dst, daddr);
-	if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
-		ipv6_addr_copy(&fl->fl6_src, &np->saddr);
-	fl->fl_ip_sport = inet->sport;
+	fl.proto = IPPROTO_UDP;
+	ipv6_addr_copy(&fl.fl6_dst, daddr);
+	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+	fl.fl_ip_sport = inet->sport;
 	
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		ipv6_addr_copy(&final, &fl->fl6_dst);
-		ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		final_p = &final;
 		connected = 0;
 	}
 
-	if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst)) {
-		fl->oif = np->mcast_oif;
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) {
+		fl.oif = np->mcast_oif;
 		connected = 0;
 	}
 
-	security_sk_classify_flow(sk, fl);
+	security_sk_classify_flow(sk, &fl);
 
-	err = ip6_sk_dst_lookup(sk, &dst, fl);
+	err = ip6_sk_dst_lookup(sk, &dst, &fl);
 	if (err)
 		goto out;
 	if (final_p)
-		ipv6_addr_copy(&fl->fl6_dst, final_p);
+		ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-	if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0)
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
 		goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl->fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -763,7 +763,7 @@ back_from_confirm:
 do_append_data:
 	up->len += ulen;
 	err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen,
-		sizeof(struct udphdr), hlimit, tclass, opt, fl,
+		sizeof(struct udphdr), hlimit, tclass, opt, &fl,
 		(struct rt6_info*)dst,
 		corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
@@ -774,10 +774,10 @@ do_append_data:
 	if (dst) {
 		if (connected) {
 			ip6_dst_store(sk, dst,
-				      ipv6_addr_equal(&fl->fl6_dst, &np->daddr) ?
+				      ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ?
 				      &np->daddr : NULL,
 #ifdef CONFIG_IPV6_SUBTREES
-				      ipv6_addr_equal(&fl->fl6_src, &np->saddr) ?
+				      ipv6_addr_equal(&fl.fl6_src, &np->saddr) ?
 				      &np->saddr :
 #endif
 				      NULL);
-- 
1.6.3.3

Attachment: signature.asc
Description: Digital signature

Reply via email to