diff --git a/net/core/skmsg.c b/net/core/skmsg.c index 4a3dc8d272957..b1dfd2c9abfe5 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -647,6 +647,13 @@ static void sk_psock_backlog(struct work_struct *work) u32 len, off; int ret; + /* Increment the psock refcnt to synchronize with close(fd) path in + * sock_map_close(), ensuring we wait for backlog thread completion + * before sk_socket freed. If refcnt increment fails, it indicates + * sock_map_close() completed with sk_socket potentially already freed. + */ + if (!sk_psock_get(psock->sk)) + return; mutex_lock(&psock->work_mutex); if (unlikely(state->skb)) { spin_lock_bh(&psock->ingress_lock); @@ -697,6 +704,7 @@ static void sk_psock_backlog(struct work_struct *work) } end: mutex_unlock(&psock->work_mutex); + sk_psock_put(psock->sk, psock); } struct sk_psock *sk_psock_init(struct sock *sk, int node)