| From beacff50edbd6c9659a6f15fc7f6126909fade29 Mon Sep 17 00:00:00 2001 |
| From: Eiichi Tsukata <eiichi.tsukata@nutanix.com> |
| Date: Sun, 21 Nov 2021 04:16:08 +0000 |
| Subject: rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer() |
| |
| From: Eiichi Tsukata <eiichi.tsukata@nutanix.com> |
| |
| commit beacff50edbd6c9659a6f15fc7f6126909fade29 upstream. |
| |
| Need to call rxrpc_put_local() for peer candidate before kfree() as it |
| holds a ref to rxrpc_local. |
| |
| [DH: v2: Changed to abstract the peer freeing code out into a function] |
| |
| Fixes: 9ebeddef58c4 ("rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record") |
| Signed-off-by: Eiichi Tsukata <eiichi.tsukata@nutanix.com> |
| Signed-off-by: David Howells <dhowells@redhat.com> |
| Reviewed-by: Marc Dionne <marc.dionne@auristor.com> |
| cc: linux-afs@lists.infradead.org |
| Link: https://lore.kernel.org/all/20211121041608.133740-2-eiichi.tsukata@nutanix.com/ # v1 |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/rxrpc/peer_object.c | 14 +++++++++----- |
| 1 file changed, 9 insertions(+), 5 deletions(-) |
| |
| --- a/net/rxrpc/peer_object.c |
| +++ b/net/rxrpc/peer_object.c |
| @@ -299,6 +299,12 @@ static struct rxrpc_peer *rxrpc_create_p |
| return peer; |
| } |
| |
| +static void rxrpc_free_peer(struct rxrpc_peer *peer) |
| +{ |
| + rxrpc_put_local(peer->local); |
| + kfree_rcu(peer, rcu); |
| +} |
| + |
| /* |
| * Set up a new incoming peer. There shouldn't be any other matching peers |
| * since we've already done a search in the list from the non-reentrant context |
| @@ -365,7 +371,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(str |
| spin_unlock_bh(&rxnet->peer_hash_lock); |
| |
| if (peer) |
| - kfree(candidate); |
| + rxrpc_free_peer(candidate); |
| else |
| peer = candidate; |
| } |
| @@ -420,8 +426,7 @@ static void __rxrpc_put_peer(struct rxrp |
| list_del_init(&peer->keepalive_link); |
| spin_unlock_bh(&rxnet->peer_hash_lock); |
| |
| - rxrpc_put_local(peer->local); |
| - kfree_rcu(peer, rcu); |
| + rxrpc_free_peer(peer); |
| } |
| |
| /* |
| @@ -457,8 +462,7 @@ void rxrpc_put_peer_locked(struct rxrpc_ |
| if (n == 0) { |
| hash_del_rcu(&peer->hash_link); |
| list_del_init(&peer->keepalive_link); |
| - rxrpc_put_local(peer->local); |
| - kfree_rcu(peer, rcu); |
| + rxrpc_free_peer(peer); |
| } |
| } |
| |