From: Greg Kroah-Hartman Date: Mon, 27 Nov 2017 11:58:16 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v3.18.85~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=779016dd601f4f3ca94a4124edcd54813bb9a68c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ipv6-only-call-ip6_route_dev_notify-once-for-netdev_unregister.patch vsock-use-new-wait-api-for-vsock_stream_sendmsg.patch --- diff --git a/queue-4.9/ipv6-only-call-ip6_route_dev_notify-once-for-netdev_unregister.patch b/queue-4.9/ipv6-only-call-ip6_route_dev_notify-once-for-netdev_unregister.patch new file mode 100644 index 00000000000..9682d13286c --- /dev/null +++ b/queue-4.9/ipv6-only-call-ip6_route_dev_notify-once-for-netdev_unregister.patch @@ -0,0 +1,48 @@ +From 76da0704507bbc51875013f6557877ab308cfd0a Mon Sep 17 00:00:00 2001 +From: WANG Cong +Date: Tue, 20 Jun 2017 11:42:27 -0700 +Subject: ipv6: only call ip6_route_dev_notify() once for NETDEV_UNREGISTER + +From: WANG Cong + +commit 76da0704507bbc51875013f6557877ab308cfd0a upstream. + +In commit 242d3a49a2a1 ("ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf") +I assumed NETDEV_REGISTER and NETDEV_UNREGISTER are paired, +unfortunately, as reported by jeffy, netdev_wait_allrefs() +could rebroadcast NETDEV_UNREGISTER event until all refs are +gone. + +We have to add an additional check to avoid this corner case. +For netdev_wait_allrefs() dev->reg_state is NETREG_UNREGISTERED, +for dev_change_net_namespace(), dev->reg_state is +NETREG_REGISTERED. So check for dev->reg_state != NETREG_UNREGISTERED. + +Fixes: 242d3a49a2a1 ("ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf") +Reported-by: jeffy +Cc: David Ahern +Signed-off-by: Cong Wang +Acked-by: David Ahern +Signed-off-by: David S. Miller +Cc: Konstantin Khlebnikov +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/route.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3495,7 +3495,11 @@ static int ip6_route_dev_notify(struct n + net->ipv6.ip6_blk_hole_entry->dst.dev = dev; + net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); + #endif +- } else if (event == NETDEV_UNREGISTER) { ++ } else if (event == NETDEV_UNREGISTER && ++ dev->reg_state != NETREG_UNREGISTERED) { ++ /* NETDEV_UNREGISTER could be fired for multiple times by ++ * netdev_wait_allrefs(). Make sure we only call this once. ++ */ + in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); diff --git a/queue-4.9/series b/queue-4.9/series index 20d62811d25..e8c2d37fdba 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -4,3 +4,5 @@ s390-disassembler-add-missing-end-marker-for-e7-table.patch s390-disassembler-increase-show_code-buffer-size.patch acpi-ec-fix-regression-related-to-triggering-source-of-ec-event-handling.patch x86-mm-fix-use-after-free-of-vma-during-userfaultfd-fault.patch +ipv6-only-call-ip6_route_dev_notify-once-for-netdev_unregister.patch +vsock-use-new-wait-api-for-vsock_stream_sendmsg.patch diff --git a/queue-4.9/vsock-use-new-wait-api-for-vsock_stream_sendmsg.patch b/queue-4.9/vsock-use-new-wait-api-for-vsock_stream_sendmsg.patch new file mode 100644 index 00000000000..68d97b5544d --- /dev/null +++ b/queue-4.9/vsock-use-new-wait-api-for-vsock_stream_sendmsg.patch @@ -0,0 +1,102 @@ +From 499fde662f1957e3cb8d192a94a099ebe19c714b Mon Sep 17 00:00:00 2001 +From: WANG Cong +Date: Fri, 19 May 2017 11:21:59 -0700 +Subject: vsock: use new wait API for vsock_stream_sendmsg() + +From: WANG Cong + +commit 499fde662f1957e3cb8d192a94a099ebe19c714b upstream. + +As reported by Michal, vsock_stream_sendmsg() could still +sleep at vsock_stream_has_space() after prepare_to_wait(): + + vsock_stream_has_space + vmci_transport_stream_has_space + vmci_qpair_produce_free_space + qp_lock + qp_acquire_queue_mutex + mutex_lock + +Just switch to the new wait API like we did for commit +d9dc8b0f8b4e ("net: fix sleeping for sk_wait_event()"). + +Reported-by: Michal Kubecek +Cc: Stefan Hajnoczi +Cc: Jorgen Hansen +Cc: "Michael S. Tsirkin" +Cc: Claudio Imbrenda +Signed-off-by: Cong Wang +Reviewed-by: Stefan Hajnoczi +Signed-off-by: David S. Miller +Cc: "Jorgen S. Hansen" +Signed-off-by: Greg Kroah-Hartman + +--- + net/vmw_vsock/af_vsock.c | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1524,8 +1524,7 @@ static int vsock_stream_sendmsg(struct s + long timeout; + int err; + struct vsock_transport_send_notify_data send_data; +- +- DEFINE_WAIT(wait); ++ DEFINE_WAIT_FUNC(wait, woken_wake_function); + + sk = sock->sk; + vsk = vsock_sk(sk); +@@ -1568,11 +1567,10 @@ static int vsock_stream_sendmsg(struct s + if (err < 0) + goto out; + +- + while (total_written < len) { + ssize_t written; + +- prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); ++ add_wait_queue(sk_sleep(sk), &wait); + while (vsock_stream_has_space(vsk) == 0 && + sk->sk_err == 0 && + !(sk->sk_shutdown & SEND_SHUTDOWN) && +@@ -1581,33 +1579,30 @@ static int vsock_stream_sendmsg(struct s + /* Don't wait for non-blocking sockets. */ + if (timeout == 0) { + err = -EAGAIN; +- finish_wait(sk_sleep(sk), &wait); ++ remove_wait_queue(sk_sleep(sk), &wait); + goto out_err; + } + + err = transport->notify_send_pre_block(vsk, &send_data); + if (err < 0) { +- finish_wait(sk_sleep(sk), &wait); ++ remove_wait_queue(sk_sleep(sk), &wait); + goto out_err; + } + + release_sock(sk); +- timeout = schedule_timeout(timeout); ++ timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout); + lock_sock(sk); + if (signal_pending(current)) { + err = sock_intr_errno(timeout); +- finish_wait(sk_sleep(sk), &wait); ++ remove_wait_queue(sk_sleep(sk), &wait); + goto out_err; + } else if (timeout == 0) { + err = -EAGAIN; +- finish_wait(sk_sleep(sk), &wait); ++ remove_wait_queue(sk_sleep(sk), &wait); + goto out_err; + } +- +- prepare_to_wait(sk_sleep(sk), &wait, +- TASK_INTERRUPTIBLE); + } +- finish_wait(sk_sleep(sk), &wait); ++ remove_wait_queue(sk_sleep(sk), &wait); + + /* These checks occur both as part of and after the loop + * conditional since we need to check before and after