]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Mon, 10 Feb 2020 03:11:55 +0000 (22:11 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 10 Feb 2020 03:11:55 +0000 (22:11 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/rxrpc-fix-service-call-disconnection.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/rxrpc-fix-service-call-disconnection.patch b/queue-5.4/rxrpc-fix-service-call-disconnection.patch
new file mode 100644 (file)
index 0000000..02df2d8
--- /dev/null
@@ -0,0 +1,63 @@
+From cb67f104d36f9904c09380c9f2915befb2b0c558 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Feb 2020 13:55:01 +0000
+Subject: rxrpc: Fix service call disconnection
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit b39a934ec72fa2b5a74123891f25273a38378b90 ]
+
+The recent patch that substituted a flag on an rxrpc_call for the
+connection pointer being NULL as an indication that a call was disconnected
+puts the set_bit in the wrong place for service calls.  This is only a
+problem if a call is implicitly terminated by a new call coming in on the
+same connection channel instead of a terminating ACK packet.
+
+In such a case, rxrpc_input_implicit_end_call() calls
+__rxrpc_disconnect_call(), which is now (incorrectly) setting the
+disconnection bit, meaning that when rxrpc_release_call() is later called,
+it doesn't call rxrpc_disconnect_call() and so the call isn't removed from
+the peer's error distribution list and the list gets corrupted.
+
+KASAN finds the issue as an access after release on a call, but the
+position at which it occurs is confusing as it appears to be related to a
+different call (the call site is where the latter call is being removed
+from the error distribution list and either the next or pprev pointer
+points to a previously released call).
+
+Fix this by moving the setting of the flag from __rxrpc_disconnect_call()
+to rxrpc_disconnect_call() in the same place that the connection pointer
+was being cleared.
+
+Fixes: 5273a191dca6 ("rxrpc: Fix NULL pointer deref due to call->conn being cleared on disconnect")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/conn_object.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
+index c0b3154f7a7e1..19e141eeed17d 100644
+--- a/net/rxrpc/conn_object.c
++++ b/net/rxrpc/conn_object.c
+@@ -171,8 +171,6 @@ void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
+       _enter("%d,%x", conn->debug_id, call->cid);
+-      set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
+-
+       if (rcu_access_pointer(chan->call) == call) {
+               /* Save the result of the call so that we can repeat it if necessary
+                * through the channel, whilst disposing of the actual call record.
+@@ -225,6 +223,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
+       __rxrpc_disconnect_call(conn, call);
+       spin_unlock(&conn->channel_lock);
++      set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
+       conn->idle_timestamp = jiffies;
+ }
+-- 
+2.20.1
+
index 6bb59e01f93d97178c9a63e7a9420558fee2624f..4564c446ee01a7c5c8c020ff8af16948e2bc12c8 100644 (file)
@@ -304,3 +304,4 @@ cifs-fix-mode-bits-from-dir-listing-when-mounted-with-modefromsid.patch
 x86-apic-msi-plug-non-maskable-msi-affinity-race.patch
 clocksource-prevent-double-add_timer_on-for-watchdog_timer.patch
 perf-core-fix-mlock-accounting-in-perf_mmap.patch
+rxrpc-fix-service-call-disconnection.patch