From: Greg Kroah-Hartman Date: Wed, 24 Jul 2013 17:53:19 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.10.3~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0abab3b4ad19128b7c509926a8383649eb7fcf7e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: af_key-fix-info-leaks-in-notify-messages.patch bridge-fix-switched-interval-for-mld-query-types.patch dummy-fix-oops-when-loading-the-dummy-failed.patch ifb-fix-oops-when-loading-the-ifb-failed.patch ifb-fix-rcu_sched-self-detected-stalls.patch ipv6-call-udp_push_pending_frames-when-uncorking-a-socket-with-af_inet-pending-data.patch ipv6-don-t-call-addrconf_dst_alloc-again-when-enable-lo.patch ipv6-ip6_sk_dst_check-must-not-assume-ipv6-dst.patch ipv6-mcast-always-hold-idev-lock-before-mca_lock.patch l2tp-add-missing-.owner-to-struct-pppox_proto.patch neighbour-fix-a-race-in-neigh_destroy.patch net-swap-ver-and-type-in-pppoe_hdr.patch sunvnet-vnet_port_remove-must-call-unregister_netdev.patch vlan-fix-a-race-in-egress-prio-management.patch x25-fix-broken-locking-in-ioctl-error-paths.patch --- diff --git a/queue-3.0/af_key-fix-info-leaks-in-notify-messages.patch b/queue-3.0/af_key-fix-info-leaks-in-notify-messages.patch new file mode 100644 index 00000000000..6562000276a --- /dev/null +++ b/queue-3.0/af_key-fix-info-leaks-in-notify-messages.patch @@ -0,0 +1,41 @@ +From 1cb7abec8733a9d4ab371d9b16f1f19ddbb1b4c8 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Wed, 26 Jun 2013 23:52:30 +0200 +Subject: af_key: fix info leaks in notify messages + +From: Mathias Krause + +[ Upstream commit a5cc68f3d63306d0d288f31edfc2ae6ef8ecd887 ] + +key_notify_sa_flush() and key_notify_policy_flush() miss to initialize +the sadb_msg_reserved member of the broadcasted message and thereby +leak 2 bytes of heap memory to listeners. Fix that. + +Signed-off-by: Mathias Krause +Cc: Steffen Klassert +Cc: "David S. Miller" +Cc: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/key/af_key.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -1705,6 +1705,7 @@ static int key_notify_sa_flush(const str + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + + pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + +@@ -2686,6 +2687,7 @@ static int key_notify_policy_flush(const + hdr->sadb_msg_version = PF_KEY_V2; + hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); ++ hdr->sadb_msg_reserved = 0; + pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); + return 0; + diff --git a/queue-3.0/bridge-fix-switched-interval-for-mld-query-types.patch b/queue-3.0/bridge-fix-switched-interval-for-mld-query-types.patch new file mode 100644 index 00000000000..645c1e579ae --- /dev/null +++ b/queue-3.0/bridge-fix-switched-interval-for-mld-query-types.patch @@ -0,0 +1,36 @@ +From ad9bc70d87b8c42a647c2bfe00ae30ff8fe3e3dc Mon Sep 17 00:00:00 2001 +From: Linus Lüssing +Date: Sun, 16 Jun 2013 23:20:34 +0200 +Subject: bridge: fix switched interval for MLD Query types + +From: Linus Lüssing + +[ Upstream commit 32de868cbc6bee010d2cee95b5071b25ecbec8c3 ] + +General Queries (the one with the Multicast Address field +set to zero / '::') are supposed to have a Maximum Response Delay +of [Query Response Interval], while for Multicast-Address-Specific +Queries it is [Last Listener Query Interval] - not the other way +round. (see RFC2710, section 7.3+7.8) + +Signed-off-by: Linus Lüssing +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_multicast.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -467,8 +467,9 @@ static struct sk_buff *br_ip6_multicast_ + skb_set_transport_header(skb, skb->len); + mldq = (struct mld_msg *) icmp6_hdr(skb); + +- interval = ipv6_addr_any(group) ? br->multicast_last_member_interval : +- br->multicast_query_response_interval; ++ interval = ipv6_addr_any(group) ? ++ br->multicast_query_response_interval : ++ br->multicast_last_member_interval; + + mldq->mld_type = ICMPV6_MGM_QUERY; + mldq->mld_code = 0; diff --git a/queue-3.0/dummy-fix-oops-when-loading-the-dummy-failed.patch b/queue-3.0/dummy-fix-oops-when-loading-the-dummy-failed.patch new file mode 100644 index 00000000000..a78d691fa0b --- /dev/null +++ b/queue-3.0/dummy-fix-oops-when-loading-the-dummy-failed.patch @@ -0,0 +1,87 @@ +From 7b73e0a1d8fee9a1c9004f0c548ddf619ec21b2f Mon Sep 17 00:00:00 2001 +From: dingtianhong +Date: Thu, 11 Jul 2013 19:04:02 +0800 +Subject: dummy: fix oops when loading the dummy failed + +From: dingtianhong + +[ Upstream commit 2c8a01894a12665d8059fad8f0a293c98a264121 ] + +We rename the dummy in modprobe.conf like this: + +install dummy0 /sbin/modprobe -o dummy0 --ignore-install dummy +install dummy1 /sbin/modprobe -o dummy1 --ignore-install dummy + +We got oops when we run the command: + +modprobe dummy0 +modprobe dummy1 + +------------[ cut here ]------------ + +[ 3302.187584] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 +[ 3302.195411] IP: [] __rtnl_link_unregister+0x9a/0xd0 +[ 3302.201844] PGD 85c94a067 PUD 8517bd067 PMD 0 +[ 3302.206305] Oops: 0002 [#1] SMP +[ 3302.299737] task: ffff88105ccea300 ti: ffff880eba4a0000 task.ti: ffff880eba4a0000 +[ 3302.307186] RIP: 0010:[] [] __rtnl_link_unregister+0x9a/0xd0 +[ 3302.316044] RSP: 0018:ffff880eba4a1dd8 EFLAGS: 00010246 +[ 3302.321332] RAX: 0000000000000000 RBX: ffffffff81a9d738 RCX: 0000000000000002 +[ 3302.328436] RDX: 0000000000000000 RSI: ffffffffa04d602c RDI: ffff880eba4a1dd8 +[ 3302.335541] RBP: ffff880eba4a1e18 R08: dead000000200200 R09: dead000000100100 +[ 3302.342644] R10: 0000000000000080 R11: 0000000000000003 R12: ffffffff81a9d788 +[ 3302.349748] R13: ffffffffa04d7020 R14: ffffffff81a9d670 R15: ffff880eba4a1dd8 +[ 3302.364910] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 3302.370630] CR2: 0000000000000008 CR3: 000000085e15e000 CR4: 00000000000427e0 +[ 3302.377734] DR0: 0000000000000003 DR1: 00000000000000b0 DR2: 0000000000000001 +[ 3302.384838] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +[ 3302.391940] Stack: +[ 3302.393944] ffff880eba4a1dd8 ffff880eba4a1dd8 ffff880eba4a1e18 ffffffffa04d70c0 +[ 3302.401350] 00000000ffffffef ffffffffa01a8000 0000000000000000 ffffffff816111c8 +[ 3302.408758] ffff880eba4a1e48 ffffffffa01a80be ffff880eba4a1e48 ffffffffa04d70c0 +[ 3302.416164] Call Trace: +[ 3302.418605] [] ? 0xffffffffa01a7fff +[ 3302.423727] [] dummy_init_module+0xbe/0x1000 [dummy0] +[ 3302.430405] [] ? 0xffffffffa01a7fff +[ 3302.435535] [] do_one_initcall+0x152/0x1b0 +[ 3302.441263] [] do_init_module+0x7b/0x200 +[ 3302.446824] [] load_module+0x4e2/0x530 +[ 3302.452215] [] ? ddebug_dyndbg_boot_param_cb+0x60/0x60 +[ 3302.458979] [] SyS_init_module+0xd1/0x130 +[ 3302.464627] [] system_call_fastpath+0x16/0x1b +[ 3302.490090] RIP [] __rtnl_link_unregister+0x9a/0xd0 +[ 3302.496607] RSP +[ 3302.500084] CR2: 0000000000000008 +[ 3302.503466] ---[ end trace 8342d49cd49f78ed ]--- + +The reason is that when loading dummy, if __rtnl_link_register() return failed, +the init_module should return and avoid take the wrong path. + +Signed-off-by: Tan Xiaojun +Signed-off-by: Ding Tianhong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/dummy.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/dummy.c ++++ b/drivers/net/dummy.c +@@ -186,6 +186,8 @@ static int __init dummy_init_module(void + + rtnl_lock(); + err = __rtnl_link_register(&dummy_link_ops); ++ if (err < 0) ++ goto out; + + for (i = 0; i < numdummies && !err; i++) { + err = dummy_init_one(); +@@ -193,6 +195,8 @@ static int __init dummy_init_module(void + } + if (err < 0) + __rtnl_link_unregister(&dummy_link_ops); ++ ++out: + rtnl_unlock(); + + return err; diff --git a/queue-3.0/ifb-fix-oops-when-loading-the-ifb-failed.patch b/queue-3.0/ifb-fix-oops-when-loading-the-ifb-failed.patch new file mode 100644 index 00000000000..78b7657fc56 --- /dev/null +++ b/queue-3.0/ifb-fix-oops-when-loading-the-ifb-failed.patch @@ -0,0 +1,39 @@ +From 4a398717fafa6f2308136913c2b5f90eed305cd3 Mon Sep 17 00:00:00 2001 +From: dingtianhong +Date: Thu, 11 Jul 2013 19:04:06 +0800 +Subject: ifb: fix oops when loading the ifb failed + +From: dingtianhong + +[ Upstream commit f2966cd5691058b8674a20766525bedeaea9cbcf ] + +If __rtnl_link_register() return faild when loading the ifb, it will +take the wrong path and get oops, so fix it just like dummy. + +Signed-off-by: Ding Tianhong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ifb.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -251,6 +251,8 @@ static int __init ifb_init_module(void) + + rtnl_lock(); + err = __rtnl_link_register(&ifb_link_ops); ++ if (err < 0) ++ goto out; + + for (i = 0; i < numifbs && !err; i++) { + err = ifb_init_one(i); +@@ -258,6 +260,8 @@ static int __init ifb_init_module(void) + } + if (err) + __rtnl_link_unregister(&ifb_link_ops); ++ ++out: + rtnl_unlock(); + + return err; diff --git a/queue-3.0/ifb-fix-rcu_sched-self-detected-stalls.patch b/queue-3.0/ifb-fix-rcu_sched-self-detected-stalls.patch new file mode 100644 index 00000000000..04a2428c35c --- /dev/null +++ b/queue-3.0/ifb-fix-rcu_sched-self-detected-stalls.patch @@ -0,0 +1,44 @@ +From cf5404b2d619bffcc8fd7d34b0ad30b67be60a3b Mon Sep 17 00:00:00 2001 +From: dingtianhong +Date: Wed, 10 Jul 2013 12:04:02 +0800 +Subject: ifb: fix rcu_sched self-detected stalls + +From: dingtianhong + +[ Upstream commit 440d57bc5ff55ec1efb3efc9cbe9420b4bbdfefa ] + +According to the commit 16b0dc29c1af9df341428f4c49ada4f626258082 +(dummy: fix rcu_sched self-detected stalls) + +Eric Dumazet fix the problem in dummy, but the ifb will occur the +same problem like the dummy modules. + +Trying to "modprobe ifb numifbs=30000" triggers : + +INFO: rcu_sched self-detected stall on CPU + +After this splat, RTNL is locked and reboot is needed. + +We must call cond_resched() to avoid this, even holding RTNL. + +Signed-off-by: Ding Tianhong +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ifb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/ifb.c ++++ b/drivers/net/ifb.c +@@ -252,8 +252,10 @@ static int __init ifb_init_module(void) + rtnl_lock(); + err = __rtnl_link_register(&ifb_link_ops); + +- for (i = 0; i < numifbs && !err; i++) ++ for (i = 0; i < numifbs && !err; i++) { + err = ifb_init_one(i); ++ cond_resched(); ++ } + if (err) + __rtnl_link_unregister(&ifb_link_ops); + rtnl_unlock(); diff --git a/queue-3.0/ipv6-call-udp_push_pending_frames-when-uncorking-a-socket-with-af_inet-pending-data.patch b/queue-3.0/ipv6-call-udp_push_pending_frames-when-uncorking-a-socket-with-af_inet-pending-data.patch new file mode 100644 index 00000000000..5b19e7f215f --- /dev/null +++ b/queue-3.0/ipv6-call-udp_push_pending_frames-when-uncorking-a-socket-with-af_inet-pending-data.patch @@ -0,0 +1,122 @@ +From 3cd2e0516746eec709d34c40865a060dab87d4a5 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Mon, 1 Jul 2013 20:21:30 +0200 +Subject: ipv6: call udp_push_pending_frames when uncorking a socket with AF_INET pending data + +From: Hannes Frederic Sowa + +[ Upstream commit 8822b64a0fa64a5dd1dfcf837c5b0be83f8c05d1 ] + +We accidentally call down to ip6_push_pending_frames when uncorking +pending AF_INET data on a ipv6 socket. This results in the following +splat (from Dave Jones): + +skbuff: skb_under_panic: text:ffffffff816765f6 len:48 put:40 head:ffff88013deb6df0 data:ffff88013deb6dec tail:0x2c end:0xc0 dev: +------------[ cut here ]------------ +kernel BUG at net/core/skbuff.c:126! +invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC +Modules linked in: dccp_ipv4 dccp 8021q garp bridge stp dlci mpoa snd_seq_dummy sctp fuse hidp tun bnep nfnetlink scsi_transport_iscsi rfcomm can_raw can_bcm af_802154 appletalk caif_socket can caif ipt_ULOG x25 rose af_key pppoe pppox ipx phonet irda llc2 ppp_generic slhc p8023 psnap p8022 llc crc_ccitt atm bluetooth ++netrom ax25 nfc rfkill rds af_rxrpc coretemp hwmon kvm_intel kvm crc32c_intel snd_hda_codec_realtek ghash_clmulni_intel microcode pcspkr snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep usb_debug snd_seq snd_seq_device snd_pcm e1000e snd_page_alloc snd_timer ptp snd pps_core soundcore xfs libcrc32c +CPU: 2 PID: 8095 Comm: trinity-child2 Not tainted 3.10.0-rc7+ #37 +task: ffff8801f52c2520 ti: ffff8801e6430000 task.ti: ffff8801e6430000 +RIP: 0010:[] [] skb_panic+0x63/0x65 +RSP: 0018:ffff8801e6431de8 EFLAGS: 00010282 +RAX: 0000000000000086 RBX: ffff8802353d3cc0 RCX: 0000000000000006 +RDX: 0000000000003b90 RSI: ffff8801f52c2ca0 RDI: ffff8801f52c2520 +RBP: ffff8801e6431e08 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000001 R11: 0000000000000001 R12: ffff88022ea0c800 +R13: ffff88022ea0cdf8 R14: ffff8802353ecb40 R15: ffffffff81cc7800 +FS: 00007f5720a10740(0000) GS:ffff880244c00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000005862000 CR3: 000000022843c000 CR4: 00000000001407e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 +Stack: + ffff88013deb6dec 000000000000002c 00000000000000c0 ffffffff81a3f6e4 + ffff8801e6431e18 ffffffff8159a9aa ffff8801e6431e90 ffffffff816765f6 + ffffffff810b756b 0000000700000002 ffff8801e6431e40 0000fea9292aa8c0 +Call Trace: + [] skb_push+0x3a/0x40 + [] ip6_push_pending_frames+0x1f6/0x4d0 + [] ? mark_held_locks+0xbb/0x140 + [] udp_v6_push_pending_frames+0x2b9/0x3d0 + [] ? udplite_getfrag+0x20/0x20 + [] udp_lib_setsockopt+0x1aa/0x1f0 + [] ? fget_light+0x387/0x4f0 + [] udpv6_setsockopt+0x34/0x40 + [] sock_common_setsockopt+0x14/0x20 + [] SyS_setsockopt+0x71/0xd0 + [] tracesys+0xdd/0xe2 +Code: 00 00 48 89 44 24 10 8b 87 d8 00 00 00 48 89 44 24 08 48 8b 87 e8 00 00 00 48 c7 c7 c0 04 aa 81 48 89 04 24 31 c0 e8 e1 7e ff ff <0f> 0b 55 48 89 e5 0f 0b 55 48 89 e5 0f 0b 55 48 89 e5 0f 0b 55 +RIP [] skb_panic+0x63/0x65 + RSP + +This patch adds a check if the pending data is of address family AF_INET +and directly calls udp_push_ending_frames from udp_v6_push_pending_frames +if that is the case. + +This bug was found by Dave Jones with trinity. + +(Also move the initialization of fl6 below the AF_INET check, even if +not strictly necessary.) + +Signed-off-by: Hannes Frederic Sowa +Cc: Dave Jones +Cc: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/udp.h | 1 + + net/ipv4/udp.c | 3 ++- + net/ipv6/udp.c | 7 ++++++- + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- a/include/net/udp.h ++++ b/include/net/udp.h +@@ -180,6 +180,7 @@ extern int udp_get_port(struct sock *sk, + extern void udp_err(struct sk_buff *, u32); + extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, + struct msghdr *msg, size_t len); ++extern int udp_push_pending_frames(struct sock *sk); + extern void udp_flush_pending_frames(struct sock *sk); + extern int udp_rcv(struct sk_buff *skb); + extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -765,7 +765,7 @@ send: + /* + * Push out all pending data as one UDP datagram. Socket is locked. + */ +-static int udp_push_pending_frames(struct sock *sk) ++int udp_push_pending_frames(struct sock *sk) + { + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +@@ -784,6 +784,7 @@ out: + up->pending = 0; + return err; + } ++EXPORT_SYMBOL(udp_push_pending_frames); + + int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, + size_t len) +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -892,11 +892,16 @@ static int udp_v6_push_pending_frames(st + struct udphdr *uh; + struct udp_sock *up = udp_sk(sk); + struct inet_sock *inet = inet_sk(sk); +- struct flowi6 *fl6 = &inet->cork.fl.u.ip6; ++ struct flowi6 *fl6; + int err = 0; + int is_udplite = IS_UDPLITE(sk); + __wsum csum = 0; + ++ if (up->pending == AF_INET) ++ return udp_push_pending_frames(sk); ++ ++ fl6 = &inet->cork.fl.u.ip6; ++ + /* Grab the skbuff where UDP header space exists. */ + if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) + goto out; diff --git a/queue-3.0/ipv6-don-t-call-addrconf_dst_alloc-again-when-enable-lo.patch b/queue-3.0/ipv6-don-t-call-addrconf_dst_alloc-again-when-enable-lo.patch new file mode 100644 index 00000000000..8aa02847b4c --- /dev/null +++ b/queue-3.0/ipv6-don-t-call-addrconf_dst_alloc-again-when-enable-lo.patch @@ -0,0 +1,39 @@ +From 8e86076db31bd948cae24528288c179e7a03b0ae Mon Sep 17 00:00:00 2001 +From: Gao feng +Date: Sun, 16 Jun 2013 11:14:30 +0800 +Subject: ipv6: don't call addrconf_dst_alloc again when enable lo + +From: Gao feng + +[ Upstream commit a881ae1f625c599b460cc8f8a7fcb1c438f699ad ] + +If we disable all of the net interfaces, and enable +un-lo interface before lo interface, we already allocated +the addrconf dst in ipv6_add_addr. So we shouldn't allocate +it again when we enable lo interface. + +Otherwise the message below will be triggered. +unregister_netdevice: waiting for sit1 to become free. Usage count = 1 + +This problem is introduced by commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f +"net IPv6 : Fix broken IPv6 routing table after loopback down-up" + +Signed-off-by: Gao feng +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2357,6 +2357,9 @@ static void init_loopback(struct net_dev + if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) + continue; + ++ if (sp_ifa->rt) ++ continue; ++ + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ diff --git a/queue-3.0/ipv6-ip6_sk_dst_check-must-not-assume-ipv6-dst.patch b/queue-3.0/ipv6-ip6_sk_dst_check-must-not-assume-ipv6-dst.patch new file mode 100644 index 00000000000..a94a9be306c --- /dev/null +++ b/queue-3.0/ipv6-ip6_sk_dst_check-must-not-assume-ipv6-dst.patch @@ -0,0 +1,52 @@ +From aa9d96ee4078613e40f7a99b75bb3cd22de17cd6 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 26 Jun 2013 04:15:07 -0700 +Subject: ipv6: ip6_sk_dst_check() must not assume ipv6 dst + +From: Eric Dumazet + +[ Upstream commit a963a37d384d71ad43b3e9e79d68d42fbe0901f3 ] + +It's possible to use AF_INET6 sockets and to connect to an IPv4 +destination. After this, socket dst cache is a pointer to a rtable, +not rt6_info. + +ip6_sk_dst_check() should check the socket dst cache is IPv6, or else +various corruptions/crashes can happen. + +Dave Jones can reproduce immediate crash with +trinity -q -l off -n -c sendmsg -c connect + +With help from Hannes Frederic Sowa + +Reported-by: Dave Jones +Reported-by: Hannes Frederic Sowa +Signed-off-by: Eric Dumazet +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -925,11 +925,17 @@ static struct dst_entry *ip6_sk_dst_chec + const struct flowi6 *fl6) + { + struct ipv6_pinfo *np = inet6_sk(sk); +- struct rt6_info *rt = (struct rt6_info *)dst; ++ struct rt6_info *rt; + + if (!dst) + goto out; + ++ if (dst->ops->family != AF_INET6) { ++ dst_release(dst); ++ return NULL; ++ } ++ ++ rt = (struct rt6_info *)dst; + /* Yes, checking route validity in not connected + * case is not very simple. Take into account, + * that we do not support routing by source, TOS, diff --git a/queue-3.0/ipv6-mcast-always-hold-idev-lock-before-mca_lock.patch b/queue-3.0/ipv6-mcast-always-hold-idev-lock-before-mca_lock.patch new file mode 100644 index 00000000000..73f84a623b5 --- /dev/null +++ b/queue-3.0/ipv6-mcast-always-hold-idev-lock-before-mca_lock.patch @@ -0,0 +1,239 @@ +From 3984f9daf9fcd33c7a00bb73ad806d9b3e3a48a8 Mon Sep 17 00:00:00 2001 +From: Amerigo Wang +Date: Sat, 29 Jun 2013 21:30:49 +0800 +Subject: ipv6,mcast: always hold idev->lock before mca_lock + +From: Amerigo Wang + +[ Upstream commit 8965779d2c0e6ab246c82a405236b1fb2adae6b2, with + some bits from commit b7b1bfce0bb68bd8f6e62a28295922785cc63781 + ("ipv6: split duplicate address detection and router solicitation timer") + to get the __ipv6_get_lladdr() used by this patch. ] + +dingtianhong reported the following deadlock detected by lockdep: + + ====================================================== + [ INFO: possible circular locking dependency detected ] + 3.4.24.05-0.1-default #1 Not tainted + ------------------------------------------------------- + ksoftirqd/0/3 is trying to acquire lock: + (&ndev->lock){+.+...}, at: [] ipv6_get_lladdr+0x74/0x120 + + but task is already holding lock: + (&mc->mca_lock){+.+...}, at: [] mld_send_report+0x40/0x150 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (&mc->mca_lock){+.+...}: + [] validate_chain+0x637/0x730 + [] __lock_acquire+0x2f7/0x500 + [] lock_acquire+0x114/0x150 + [] rt_spin_lock+0x4a/0x60 + [] igmp6_group_added+0x3b/0x120 + [] ipv6_mc_up+0x38/0x60 + [] ipv6_find_idev+0x3d/0x80 + [] addrconf_notify+0x3d5/0x4b0 + [] notifier_call_chain+0x3f/0x80 + [] raw_notifier_call_chain+0x11/0x20 + [] call_netdevice_notifiers+0x32/0x60 + [] __dev_notify_flags+0x34/0x80 + [] dev_change_flags+0x40/0x70 + [] do_setlink+0x237/0x8a0 + [] rtnl_newlink+0x3ec/0x600 + [] rtnetlink_rcv_msg+0x160/0x310 + [] netlink_rcv_skb+0x89/0xb0 + [] rtnetlink_rcv+0x27/0x40 + [] netlink_unicast+0x140/0x180 + [] netlink_sendmsg+0x33e/0x380 + [] sock_sendmsg+0x112/0x130 + [] __sys_sendmsg+0x44e/0x460 + [] sys_sendmsg+0x44/0x70 + [] system_call_fastpath+0x16/0x1b + + -> #0 (&ndev->lock){+.+...}: + [] check_prev_add+0x3de/0x440 + [] validate_chain+0x637/0x730 + [] __lock_acquire+0x2f7/0x500 + [] lock_acquire+0x114/0x150 + [] rt_read_lock+0x42/0x60 + [] ipv6_get_lladdr+0x74/0x120 + [] mld_newpack+0xb6/0x160 + [] add_grhead+0xab/0xc0 + [] add_grec+0x3ab/0x460 + [] mld_send_report+0x5a/0x150 + [] igmp6_timer_handler+0x4e/0xb0 + [] call_timer_fn+0xca/0x1d0 + [] run_timer_softirq+0x1df/0x2e0 + [] handle_pending_softirqs+0xf7/0x1f0 + [] __do_softirq_common+0x7b/0xf0 + [] __thread_do_softirq+0x1af/0x210 + [] run_ksoftirqd+0xe1/0x1f0 + [] kthread+0xae/0xc0 + [] kernel_thread_helper+0x4/0x10 + +actually we can just hold idev->lock before taking pmc->mca_lock, +and avoid taking idev->lock again when iterating idev->addr_list, +since the upper callers of mld_newpack() already take +read_lock_bh(&idev->lock). + +Reported-by: dingtianhong +Cc: dingtianhong +Cc: Hideaki YOSHIFUJI +Cc: David S. Miller +Cc: Hannes Frederic Sowa +Tested-by: Ding Tianhong +Tested-by: Chen Weilong +Signed-off-by: Cong Wang +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/addrconf.h | 3 +++ + net/ipv6/addrconf.c | 28 ++++++++++++++++++---------- + net/ipv6/mcast.c | 18 ++++++++++-------- + 3 files changed, 31 insertions(+), 18 deletions(-) + +--- a/include/net/addrconf.h ++++ b/include/net/addrconf.h +@@ -81,6 +81,9 @@ extern int ipv6_dev_get_saddr(struct n + const struct in6_addr *daddr, + unsigned int srcprefs, + struct in6_addr *saddr); ++extern int __ipv6_get_lladdr(struct inet6_dev *idev, ++ struct in6_addr *addr, ++ unsigned char banned_flags); + extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *addr, + unsigned char banned_flags); +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1235,6 +1235,23 @@ try_nextdev: + } + EXPORT_SYMBOL(ipv6_dev_get_saddr); + ++int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr, ++ unsigned char banned_flags) ++{ ++ struct inet6_ifaddr *ifp; ++ int err = -EADDRNOTAVAIL; ++ ++ list_for_each_entry(ifp, &idev->addr_list, if_list) { ++ if (ifp->scope == IFA_LINK && ++ !(ifp->flags & banned_flags)) { ++ ipv6_addr_copy(addr, &ifp->addr); ++ err = 0; ++ break; ++ } ++ } ++ return err; ++} ++ + int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) + { +@@ -1244,17 +1261,8 @@ int ipv6_get_lladdr(struct net_device *d + rcu_read_lock(); + idev = __in6_dev_get(dev); + if (idev) { +- struct inet6_ifaddr *ifp; +- + read_lock_bh(&idev->lock); +- list_for_each_entry(ifp, &idev->addr_list, if_list) { +- if (ifp->scope == IFA_LINK && +- !(ifp->flags & banned_flags)) { +- ipv6_addr_copy(addr, &ifp->addr); +- err = 0; +- break; +- } +- } ++ err = __ipv6_get_lladdr(idev, addr, banned_flags); + read_unlock_bh(&idev->lock); + } + rcu_read_unlock(); +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1334,8 +1334,9 @@ mld_scount(struct ifmcaddr6 *pmc, int ty + return scount; + } + +-static struct sk_buff *mld_newpack(struct net_device *dev, int size) ++static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size) + { ++ struct net_device *dev = idev->dev; + struct net *net = dev_net(dev); + struct sock *sk = net->ipv6.igmp_sk; + struct sk_buff *skb; +@@ -1358,7 +1359,7 @@ static struct sk_buff *mld_newpack(struc + + skb_reserve(skb, LL_RESERVED_SPACE(dev)); + +- if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { ++ if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address + * when a valid link-local address is not available. +@@ -1461,7 +1462,7 @@ static struct sk_buff *add_grhead(struct + struct mld2_grec *pgr; + + if (!skb) +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(pmc->idev, dev->mtu); + if (!skb) + return NULL; + pgr = (struct mld2_grec *)skb_put(skb, sizeof(struct mld2_grec)); +@@ -1481,7 +1482,8 @@ static struct sk_buff *add_grhead(struct + static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, + int type, int gdeleted, int sdeleted) + { +- struct net_device *dev = pmc->idev->dev; ++ struct inet6_dev *idev = pmc->idev; ++ struct net_device *dev = idev->dev; + struct mld2_report *pmr; + struct mld2_grec *pgr = NULL; + struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; +@@ -1510,7 +1512,7 @@ static struct sk_buff *add_grec(struct s + AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + } + } + first = 1; +@@ -1537,7 +1539,7 @@ static struct sk_buff *add_grec(struct s + pgr->grec_nsrcs = htons(scount); + if (skb) + mld_sendpack(skb); +- skb = mld_newpack(dev, dev->mtu); ++ skb = mld_newpack(idev, dev->mtu); + first = 1; + scount = 0; + } +@@ -1592,8 +1594,8 @@ static void mld_send_report(struct inet6 + struct sk_buff *skb = NULL; + int type; + ++ read_lock_bh(&idev->lock); + if (!pmc) { +- read_lock_bh(&idev->lock); + for (pmc=idev->mc_list; pmc; pmc=pmc->next) { + if (pmc->mca_flags & MAF_NOREPORT) + continue; +@@ -1605,7 +1607,6 @@ static void mld_send_report(struct inet6 + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } +- read_unlock_bh(&idev->lock); + } else { + spin_lock_bh(&pmc->mca_lock); + if (pmc->mca_sfcount[MCAST_EXCLUDE]) +@@ -1615,6 +1616,7 @@ static void mld_send_report(struct inet6 + skb = add_grec(skb, pmc, type, 0, 0); + spin_unlock_bh(&pmc->mca_lock); + } ++ read_unlock_bh(&idev->lock); + if (skb) + mld_sendpack(skb); + } diff --git a/queue-3.0/l2tp-add-missing-.owner-to-struct-pppox_proto.patch b/queue-3.0/l2tp-add-missing-.owner-to-struct-pppox_proto.patch new file mode 100644 index 00000000000..e4ccc59f81f --- /dev/null +++ b/queue-3.0/l2tp-add-missing-.owner-to-struct-pppox_proto.patch @@ -0,0 +1,31 @@ +From c924b773ce23575ad92a2ba852b01a739ef02381 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Tue, 2 Jul 2013 09:02:07 +0800 +Subject: l2tp: add missing .owner to struct pppox_proto + +From: Wei Yongjun + +[ Upstream commit e1558a93b61962710733dc8c11a2bc765607f1cd ] + +Add missing .owner of struct pppox_proto. This prevents the +module from being removed from underneath its users. + +Signed-off-by: Wei Yongjun +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -1771,7 +1771,8 @@ static const struct proto_ops pppol2tp_o + + static const struct pppox_proto pppol2tp_proto = { + .create = pppol2tp_create, +- .ioctl = pppol2tp_ioctl ++ .ioctl = pppol2tp_ioctl, ++ .owner = THIS_MODULE, + }; + + #ifdef CONFIG_L2TP_V3 diff --git a/queue-3.0/neighbour-fix-a-race-in-neigh_destroy.patch b/queue-3.0/neighbour-fix-a-race-in-neigh_destroy.patch new file mode 100644 index 00000000000..8e65974a863 --- /dev/null +++ b/queue-3.0/neighbour-fix-a-race-in-neigh_destroy.patch @@ -0,0 +1,78 @@ +From 9d5f64053500cda4768dcc1ba2310a5e4b111b92 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 28 Jun 2013 02:37:42 -0700 +Subject: neighbour: fix a race in neigh_destroy() + +From: Eric Dumazet + +[ Upstream commit c9ab4d85de222f3390c67aedc9c18a50e767531e ] + +There is a race in neighbour code, because neigh_destroy() uses +skb_queue_purge(&neigh->arp_queue) without holding neighbour lock, +while other parts of the code assume neighbour rwlock is what +protects arp_queue + +Convert all skb_queue_purge() calls to the __skb_queue_purge() variant + +Use __skb_queue_head_init() instead of skb_queue_head_init() +to make clear we do not use arp_queue.lock + +And hold neigh->lock in neigh_destroy() to close the race. + +Reported-by: Joe Jin +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/neighbour.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -237,7 +237,7 @@ static void neigh_flush_dev(struct neigh + we must kill timers etc. and move + it to safe state. + */ +- skb_queue_purge(&n->arp_queue); ++ __skb_queue_purge(&n->arp_queue); + n->output = neigh_blackhole; + if (n->nud_state & NUD_VALID) + n->nud_state = NUD_NOARP; +@@ -291,7 +291,7 @@ static struct neighbour *neigh_alloc(str + if (!n) + goto out_entries; + +- skb_queue_head_init(&n->arp_queue); ++ __skb_queue_head_init(&n->arp_queue); + rwlock_init(&n->lock); + seqlock_init(&n->ha_lock); + n->updated = n->used = now; +@@ -712,7 +712,9 @@ void neigh_destroy(struct neighbour *nei + hh_cache_put(hh); + } + +- skb_queue_purge(&neigh->arp_queue); ++ write_lock_bh(&neigh->lock); ++ __skb_queue_purge(&neigh->arp_queue); ++ write_unlock_bh(&neigh->lock); + + dev_put(neigh->dev); + neigh_parms_put(neigh->parms); +@@ -864,7 +866,7 @@ static void neigh_invalidate(struct neig + neigh->ops->error_report(neigh, skb); + write_lock(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + } + + /* Called when a timer expires for a neighbour entry. */ +@@ -1188,7 +1190,7 @@ int neigh_update(struct neighbour *neigh + + write_lock_bh(&neigh->lock); + } +- skb_queue_purge(&neigh->arp_queue); ++ __skb_queue_purge(&neigh->arp_queue); + } + out: + if (update_isrouter) { diff --git a/queue-3.0/net-swap-ver-and-type-in-pppoe_hdr.patch b/queue-3.0/net-swap-ver-and-type-in-pppoe_hdr.patch new file mode 100644 index 00000000000..8eb2542ff0e --- /dev/null +++ b/queue-3.0/net-swap-ver-and-type-in-pppoe_hdr.patch @@ -0,0 +1,34 @@ +From 0d632f1515d9e23126b623f281cf610d1ca4681f Mon Sep 17 00:00:00 2001 +From: Changli Gao +Date: Sat, 29 Jun 2013 00:15:51 +0800 +Subject: net: Swap ver and type in pppoe_hdr + +From: Changli Gao + +[ Upstream commit b1a5a34bd0b8767ea689e68f8ea513e9710b671e ] + +Ver and type in pppoe_hdr should be swapped as defined by RFC2516 +section-4. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/if_pppox.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/if_pppox.h ++++ b/include/linux/if_pppox.h +@@ -127,11 +127,11 @@ struct pppoe_tag { + + struct pppoe_hdr { + #if defined(__LITTLE_ENDIAN_BITFIELD) +- __u8 ver : 4; + __u8 type : 4; ++ __u8 ver : 4; + #elif defined(__BIG_ENDIAN_BITFIELD) +- __u8 type : 4; + __u8 ver : 4; ++ __u8 type : 4; + #else + #error "Please fix " + #endif diff --git a/queue-3.0/series b/queue-3.0/series index fc290f14d33..4aeb4c1919c 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -10,3 +10,18 @@ perf-fix-perf_lock_task_context-vs-rcu.patch sparc32-vm_area_struct-access-for-old-sun-sparcs.patch sparc64-address-congruence-property.patch sparc-tsb-must-be-flushed-before-tlb.patch +bridge-fix-switched-interval-for-mld-query-types.patch +ipv6-don-t-call-addrconf_dst_alloc-again-when-enable-lo.patch +ipv6-ip6_sk_dst_check-must-not-assume-ipv6-dst.patch +af_key-fix-info-leaks-in-notify-messages.patch +neighbour-fix-a-race-in-neigh_destroy.patch +x25-fix-broken-locking-in-ioctl-error-paths.patch +net-swap-ver-and-type-in-pppoe_hdr.patch +ipv6-mcast-always-hold-idev-lock-before-mca_lock.patch +l2tp-add-missing-.owner-to-struct-pppox_proto.patch +ipv6-call-udp_push_pending_frames-when-uncorking-a-socket-with-af_inet-pending-data.patch +sunvnet-vnet_port_remove-must-call-unregister_netdev.patch +ifb-fix-rcu_sched-self-detected-stalls.patch +dummy-fix-oops-when-loading-the-dummy-failed.patch +ifb-fix-oops-when-loading-the-ifb-failed.patch +vlan-fix-a-race-in-egress-prio-management.patch diff --git a/queue-3.0/sunvnet-vnet_port_remove-must-call-unregister_netdev.patch b/queue-3.0/sunvnet-vnet_port_remove-must-call-unregister_netdev.patch new file mode 100644 index 00000000000..a6b60431ec3 --- /dev/null +++ b/queue-3.0/sunvnet-vnet_port_remove-must-call-unregister_netdev.patch @@ -0,0 +1,30 @@ +From e7af25be212da8478e4e304cf3842c43a1852934 Mon Sep 17 00:00:00 2001 +From: Dave Kleikamp +Date: Mon, 1 Jul 2013 16:49:22 -0500 +Subject: sunvnet: vnet_port_remove must call unregister_netdev + +From: Dave Kleikamp + +[ Upstream commit aabb9875d02559ab9b928cd6f259a5cc4c21a589 ] + +The missing call to unregister_netdev() leaves the interface active +after the driver is unloaded by rmmod. + +Signed-off-by: Dave Kleikamp +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/sunvnet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/sunvnet.c ++++ b/drivers/net/sunvnet.c +@@ -1248,6 +1248,8 @@ static int vnet_port_remove(struct vio_d + dev_set_drvdata(&vdev->dev, NULL); + + kfree(port); ++ ++ unregister_netdev(vp->dev); + } + return 0; + } diff --git a/queue-3.0/vlan-fix-a-race-in-egress-prio-management.patch b/queue-3.0/vlan-fix-a-race-in-egress-prio-management.patch new file mode 100644 index 00000000000..8438bf0439c --- /dev/null +++ b/queue-3.0/vlan-fix-a-race-in-egress-prio-management.patch @@ -0,0 +1,47 @@ +From f5b405a52fdff820fd6c5b8ba9eb606de57c434e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 18 Jul 2013 09:35:10 -0700 +Subject: vlan: fix a race in egress prio management + +From: Eric Dumazet + +[ Upstream commit 3e3aac497513c669e1c62c71e1d552ea85c1d974 ] + +egress_priority_map[] hash table updates are protected by rtnl, +and we never remove elements until device is dismantled. + +We have to make sure that before inserting an new element in hash table, +all its fields are committed to memory or else another cpu could +find corrupt values and crash. + +Signed-off-by: Eric Dumazet +Cc: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/8021q/vlan_dev.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -70,6 +70,8 @@ vlan_dev_get_egress_qos_mask(struct net_ + { + struct vlan_priority_tci_mapping *mp; + ++ smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */ ++ + mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)]; + while (mp) { + if (mp->priority == skb->priority) { +@@ -230,6 +232,11 @@ int vlan_dev_set_egress_priority(const s + np->next = mp; + np->priority = skb_prio; + np->vlan_qos = vlan_qos; ++ /* Before inserting this element in hash table, make sure all its fields ++ * are committed to memory. ++ * coupled with smp_rmb() in vlan_dev_get_egress_qos_mask() ++ */ ++ smp_wmb(); + vlan->egress_priority_map[skb_prio & 0xF] = np; + if (vlan_qos) + vlan->nr_egress_mappings++; diff --git a/queue-3.0/x25-fix-broken-locking-in-ioctl-error-paths.patch b/queue-3.0/x25-fix-broken-locking-in-ioctl-error-paths.patch new file mode 100644 index 00000000000..de592815066 --- /dev/null +++ b/queue-3.0/x25-fix-broken-locking-in-ioctl-error-paths.patch @@ -0,0 +1,64 @@ +From 12d19dd7e86a89d0388295cbda4758a22b9c2b40 Mon Sep 17 00:00:00 2001 +From: Dave Jones +Date: Fri, 28 Jun 2013 12:13:52 -0400 +Subject: x25: Fix broken locking in ioctl error paths. + +From: Dave Jones + +[ Upstream commit 4ccb93ce7439b63c31bc7597bfffd13567fa483d ] + +Two of the x25 ioctl cases have error paths that break out of the function without +unlocking the socket, leading to this warning: + +================================================ +[ BUG: lock held when returning to user space! ] +3.10.0-rc7+ #36 Not tainted +------------------------------------------------ +trinity-child2/31407 is leaving the kernel with locks still held! +1 lock held by trinity-child2/31407: + #0: (sk_lock-AF_X25){+.+.+.}, at: [] x25_ioctl+0x8a/0x740 [x25] + +Signed-off-by: Dave Jones +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/x25/af_x25.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1584,11 +1584,11 @@ out_cud_release: + case SIOCX25CALLACCPTAPPRV: { + rc = -EINVAL; + lock_sock(sk); +- if (sk->sk_state != TCP_CLOSE) +- break; +- clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ if (sk->sk_state == TCP_CLOSE) { ++ clear_bit(X25_ACCPT_APPRV_FLAG, &x25->flags); ++ rc = 0; ++ } + release_sock(sk); +- rc = 0; + break; + } + +@@ -1596,14 +1596,15 @@ out_cud_release: + rc = -EINVAL; + lock_sock(sk); + if (sk->sk_state != TCP_ESTABLISHED) +- break; ++ goto out_sendcallaccpt_release; + /* must call accptapprv above */ + if (test_bit(X25_ACCPT_APPRV_FLAG, &x25->flags)) +- break; ++ goto out_sendcallaccpt_release; + x25_write_internal(sk, X25_CALL_ACCEPTED); + x25->state = X25_STATE_3; +- release_sock(sk); + rc = 0; ++out_sendcallaccpt_release: ++ release_sock(sk); + break; + } +