diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index cac1b5487..f2530bebe 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -81,8 +81,14 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device, nfc_llcp_socket_purge(llcp_sock); - if (sk->sk_state == LLCP_CONNECTED) + if (sk->sk_state == LLCP_CONNECTED) { nfc_put_device(llcp_sock->dev); + llcp_sock->dev = NULL; + } else if (sk->sk_state == LLCP_BOUND || + sk->sk_state == LLCP_LISTEN) { + /* bind() already dropped its temporary device reference. */ + llcp_sock->dev = NULL; + } if (sk->sk_state == LLCP_LISTEN) { struct nfc_llcp_sock *lsk, *n; @@ -1276,6 +1282,10 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local, sk = &llcp_sock->sk; + /* Bound and listening sockets do not own a device reference. */ + if (sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN) + llcp_sock->dev = NULL; + sk->sk_err = ENXIO; sk->sk_state = LLCP_CLOSED; sk->sk_state_change(sk);