From a009bec69328842cab49f1e8c5e18003ef0479bd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 18 Feb 2022 11:50:36 +0100 Subject: [PATCH] 4.9-stable patches added patches: vsock-correct-removal-of-socket-from-the-list.patch vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch --- queue-4.9/series | 2 + ...rect-removal-of-socket-from-the-list.patch | 94 +++++++++++++++++++ ...n-connect-is-interrupted-by-a-signal.patch | 46 +++++++++ 3 files changed, 142 insertions(+) create mode 100644 queue-4.9/vsock-correct-removal-of-socket-from-the-list.patch create mode 100644 queue-4.9/vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch diff --git a/queue-4.9/series b/queue-4.9/series index 9346c4a264c..0e6a0722909 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -14,3 +14,5 @@ quota-make-dquot_quota_sync-return-errors-from-sync_.patch drm-radeon-fix-backlight-control-on-imac-12-1.patch xfrm-don-t-accidentally-set-rto_onlink-in-decode_session4.patch taskstats-cleanup-the-use-of-task-exit_code.patch +vsock-correct-removal-of-socket-from-the-list.patch +vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch diff --git a/queue-4.9/vsock-correct-removal-of-socket-from-the-list.patch b/queue-4.9/vsock-correct-removal-of-socket-from-the-list.patch new file mode 100644 index 00000000000..363c3cb9d15 --- /dev/null +++ b/queue-4.9/vsock-correct-removal-of-socket-from-the-list.patch @@ -0,0 +1,94 @@ +From d5afa82c977ea06f7119058fa0eb8519ea501031 Mon Sep 17 00:00:00 2001 +From: Sunil Muthuswamy +Date: Thu, 13 Jun 2019 03:52:27 +0000 +Subject: vsock: correct removal of socket from the list + +From: Sunil Muthuswamy + +commit d5afa82c977ea06f7119058fa0eb8519ea501031 upstream. + +The current vsock code for removal of socket from the list is both +subject to race and inefficient. It takes the lock, checks whether +the socket is in the list, drops the lock and if the socket was on the +list, deletes it from the list. This is subject to race because as soon +as the lock is dropped once it is checked for presence, that condition +cannot be relied upon for any decision. It is also inefficient because +if the socket is present in the list, it takes the lock twice. + +Signed-off-by: Sunil Muthuswamy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/vmw_vsock/af_vsock.c | 38 +++++++------------------------------- + 1 file changed, 7 insertions(+), 31 deletions(-) + +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -279,7 +279,8 @@ EXPORT_SYMBOL_GPL(vsock_insert_connected + void vsock_remove_bound(struct vsock_sock *vsk) + { + spin_lock_bh(&vsock_table_lock); +- __vsock_remove_bound(vsk); ++ if (__vsock_in_bound_table(vsk)) ++ __vsock_remove_bound(vsk); + spin_unlock_bh(&vsock_table_lock); + } + EXPORT_SYMBOL_GPL(vsock_remove_bound); +@@ -287,7 +288,8 @@ EXPORT_SYMBOL_GPL(vsock_remove_bound); + void vsock_remove_connected(struct vsock_sock *vsk) + { + spin_lock_bh(&vsock_table_lock); +- __vsock_remove_connected(vsk); ++ if (__vsock_in_connected_table(vsk)) ++ __vsock_remove_connected(vsk); + spin_unlock_bh(&vsock_table_lock); + } + EXPORT_SYMBOL_GPL(vsock_remove_connected); +@@ -323,35 +325,10 @@ struct sock *vsock_find_connected_socket + } + EXPORT_SYMBOL_GPL(vsock_find_connected_socket); + +-static bool vsock_in_bound_table(struct vsock_sock *vsk) +-{ +- bool ret; +- +- spin_lock_bh(&vsock_table_lock); +- ret = __vsock_in_bound_table(vsk); +- spin_unlock_bh(&vsock_table_lock); +- +- return ret; +-} +- +-static bool vsock_in_connected_table(struct vsock_sock *vsk) +-{ +- bool ret; +- +- spin_lock_bh(&vsock_table_lock); +- ret = __vsock_in_connected_table(vsk); +- spin_unlock_bh(&vsock_table_lock); +- +- return ret; +-} +- + void vsock_remove_sock(struct vsock_sock *vsk) + { +- if (vsock_in_bound_table(vsk)) +- vsock_remove_bound(vsk); +- +- if (vsock_in_connected_table(vsk)) +- vsock_remove_connected(vsk); ++ vsock_remove_bound(vsk); ++ vsock_remove_connected(vsk); + } + EXPORT_SYMBOL_GPL(vsock_remove_sock); + +@@ -482,8 +459,7 @@ static void vsock_pending_work(struct wo + * incoming packets can't find this socket, and to reduce the reference + * count. + */ +- if (vsock_in_connected_table(vsk)) +- vsock_remove_connected(vsk); ++ vsock_remove_connected(vsk); + + sk->sk_state = SS_FREE; + diff --git a/queue-4.9/vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch b/queue-4.9/vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch new file mode 100644 index 00000000000..ee5339e099a --- /dev/null +++ b/queue-4.9/vsock-remove-vsock-from-connected-table-when-connect-is-interrupted-by-a-signal.patch @@ -0,0 +1,46 @@ +From b9208492fcaecff8f43915529ae34b3bcb03877c Mon Sep 17 00:00:00 2001 +From: Seth Forshee +Date: Thu, 17 Feb 2022 08:13:12 -0600 +Subject: vsock: remove vsock from connected table when connect is interrupted by a signal + +From: Seth Forshee + +commit b9208492fcaecff8f43915529ae34b3bcb03877c upstream. + +vsock_connect() expects that the socket could already be in the +TCP_ESTABLISHED state when the connecting task wakes up with a signal +pending. If this happens the socket will be in the connected table, and +it is not removed when the socket state is reset. In this situation it's +common for the process to retry connect(), and if the connection is +successful the socket will be added to the connected table a second +time, corrupting the list. + +Prevent this by calling vsock_remove_connected() if a signal is received +while waiting for a connection. This is harmless if the socket is not in +the connected table, and if it is in the table then removing it will +prevent list corruption from a double add. + +Note for backporting: this patch requires d5afa82c977e ("vsock: correct +removal of socket from the list"), which is in all current stable trees +except 4.9.y. + +Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") +Signed-off-by: Seth Forshee +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20220217141312.2297547-1-sforshee@digitalocean.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/vmw_vsock/af_vsock.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1220,6 +1220,7 @@ static int vsock_stream_connect(struct s + sk->sk_state = SS_UNCONNECTED; + sock->state = SS_UNCONNECTED; + vsock_transport_cancel_pkt(vsk); ++ vsock_remove_connected(vsk); + goto out_wait; + } else if (timeout == 0) { + err = -ETIMEDOUT; -- 2.47.3