diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index d257ed3b732a..e3f57fa31914 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -14,6 +14,8 @@ #include "nfc.h" #include "llcp.h" +DEFINE_MUTEX(sock_release_mutex); + static int sock_wait_state(struct sock *sk, int state, unsigned long timeo) { DECLARE_WAITQUEUE(wait, current); @@ -582,6 +584,7 @@ static __poll_t llcp_sock_poll(struct file *file, struct socket *sock, static int llcp_sock_release(struct socket *sock) { + mutex_lock(&sock_release_mutex); struct sock *sk = sock->sk; struct nfc_llcp_local *local; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); @@ -630,7 +633,7 @@ static int llcp_sock_release(struct socket *sock) * reply with DM PDUs before sending the DISC one. */ if (sk->sk_state == LLCP_DISCONNECTING) - return err; + goto release; if (sock->type == SOCK_RAW) nfc_llcp_sock_unlink(&local->raw_sockets, sk); @@ -641,6 +644,8 @@ static int llcp_sock_release(struct socket *sock) sock_orphan(sk); sock_put(sk); +release: + mutex_unlock(&sock_release_mutex); return err; }