[PATCH 2/2] rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()

Marc Dionne marc.dionne at auristor.com
Fri Nov 26 05:15:41 PST 2021


On Wed, Nov 24, 2021 at 10:38 AM David Howells <dhowells at redhat.com> wrote:
>
> From: Eiichi Tsukata <eiichi.tsukata at nutanix.com>
>
> 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 at nutanix.com>
> Signed-off-by: David Howells <dhowells at redhat.com>
> cc: Marc Dionne <marc.dionne at auristor.com>
> cc: linux-afs at lists.infradead.org
> Link: https://lore.kernel.org/all/20211121041608.133740-2-eiichi.tsukata@nutanix.com/ # v1
> ---
>
>  net/rxrpc/peer_object.c |   14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
> index 68396d052052..0298fe2ad6d3 100644
> --- a/net/rxrpc/peer_object.c
> +++ b/net/rxrpc/peer_object.c
> @@ -299,6 +299,12 @@ static struct rxrpc_peer *rxrpc_create_peer(struct rxrpc_sock *rx,
>         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(struct rxrpc_sock *rx,
>                 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 rxrpc_peer *peer)
>         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_peer *peer)
>         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);
>         }
>  }

Reviewed-by: Marc Dionne <marc.dionne at auristor.com>

Marc



More information about the linux-afs mailing list