summaryrefslogtreecommitdiffstats
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-08-12 23:30:06 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-29 08:30:28 +0200
commitfa321a9ce5992f2ba336c5bf032e874e7b81b0b2 (patch)
tree866a43d022d5c201cfd4390e58b4fcf92556401a /net/rxrpc
parentd2783ccec7e0310343238371e5ab82c73e14aa67 (diff)
downloadlinux-stable-fa321a9ce5992f2ba336c5bf032e874e7b81b0b2.tar.gz
linux-stable-fa321a9ce5992f2ba336c5bf032e874e7b81b0b2.tar.bz2
linux-stable-fa321a9ce5992f2ba336c5bf032e874e7b81b0b2.zip
rxrpc: Fix local endpoint replacement
[ Upstream commit b00df840fb4004b7087940ac5f68801562d0d2de ] When a local endpoint (struct rxrpc_local) ceases to be in use by any AF_RXRPC sockets, it starts the process of being destroyed, but this doesn't cause it to be removed from the namespace endpoint list immediately as tearing it down isn't trivial and can't be done in softirq context, so it gets deferred. If a new socket comes along that wants to bind to the same endpoint, a new rxrpc_local object will be allocated and rxrpc_lookup_local() will use list_replace() to substitute the new one for the old. Then, when the dying object gets to rxrpc_local_destroyer(), it is removed unconditionally from whatever list it is on by calling list_del_init(). However, list_replace() doesn't reset the pointers in the replaced list_head and so the list_del_init() will likely corrupt the local endpoints list. Fix this by using list_replace_init() instead. Fixes: 730c5fd42c1e ("rxrpc: Fix local endpoint refcounting") Reported-by: syzbot+193e29e9387ea5837f1d@syzkaller.appspotmail.com Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/local_object.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 9368dae857ca..68e9342fd433 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -283,7 +283,7 @@ struct rxrpc_local *rxrpc_lookup_local(struct net *net,
goto sock_error;
if (cursor != &rxnet->local_endpoints)
- list_replace(cursor, &local->link);
+ list_replace_init(cursor, &local->link);
else
list_add_tail(&local->link, cursor);
age = "new";