On 01/03/2018 04:47 AM, John Fastabend wrote:
> Add psock NULL check to handle a racing sock event that can get the
> sk_callback_lock before this case but after xchg happens causing the
> refcnt to hit zero and sock user data (psock) to be null and queued
> for garbage collection.
> 
> Also add a comment in the code because this is a bit subtle and
> not obvious in my opinion.
> 
> Signed-off-by: John Fastabend <[email protected]>
> ---
>  kernel/bpf/sockmap.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
> index 5ee2e41..dfbbde2 100644
> --- a/kernel/bpf/sockmap.c
> +++ b/kernel/bpf/sockmap.c
> @@ -591,6 +591,13 @@ static void sock_map_free(struct bpf_map *map)
>  
>               write_lock_bh(&sock->sk_callback_lock);
>               psock = smap_psock_sk(sock);
> +             /* This check handles a racing sock event that can get the
> +              * sk_callback_lock before this case but after xchg happens
> +              * causing the refcnt to hit zero and sock user data (psock)
> +              * to be null and queued for garbage collection.
> +              */
> +             if (unlikely(!psock))
> +                     continue;

Don't we need a write_unlock_bh(&sock->sk_callback_lock) before the continue?

>               smap_list_remove(psock, &stab->sock_map[i]);
>               smap_release_sock(psock, sock);
>               write_unlock_bh(&sock->sk_callback_lock);
> 

Reply via email to