Skip to content

Commit c61760e

Browse files
Or Cohendavem330
authored andcommitted
net/nfc: fix use-after-free llcp_sock_bind/connect
Commits 8a4cd82 ("nfc: fix refcount leak in llcp_sock_connect()") and c33b1cc ("nfc: fix refcount leak in llcp_sock_bind()") fixed a refcount leak bug in bind/connect but introduced a use-after-free if the same local is assigned to 2 different sockets. This can be triggered by the following simple program: int sock1 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP ); int sock2 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP ); memset( &addr, 0, sizeof(struct sockaddr_nfc_llcp) ); addr.sa_family = AF_NFC; addr.nfc_protocol = NFC_PROTO_NFC_DEP; bind( sock1, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) ) bind( sock2, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) ) close(sock1); close(sock2); Fix this by assigning NULL to llcp_sock->local after calling nfc_llcp_local_put. This addresses CVE-2021-23134. Reported-by: Or Cohen <[email protected]> Reported-by: Nadav Markus <[email protected]> Fixes: c33b1cc ("nfc: fix refcount leak in llcp_sock_bind()") Signed-off-by: Or Cohen <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8d43259 commit c61760e

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

net/nfc/llcp_sock.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,14 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
109109
GFP_KERNEL);
110110
if (!llcp_sock->service_name) {
111111
nfc_llcp_local_put(llcp_sock->local);
112+
llcp_sock->local = NULL;
112113
ret = -ENOMEM;
113114
goto put_dev;
114115
}
115116
llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
116117
if (llcp_sock->ssap == LLCP_SAP_MAX) {
117118
nfc_llcp_local_put(llcp_sock->local);
119+
llcp_sock->local = NULL;
118120
kfree(llcp_sock->service_name);
119121
llcp_sock->service_name = NULL;
120122
ret = -EADDRINUSE;
@@ -709,6 +711,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
709711
llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
710712
if (llcp_sock->ssap == LLCP_SAP_MAX) {
711713
nfc_llcp_local_put(llcp_sock->local);
714+
llcp_sock->local = NULL;
712715
ret = -ENOMEM;
713716
goto put_dev;
714717
}
@@ -756,6 +759,7 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
756759
sock_llcp_release:
757760
nfc_llcp_put_ssap(local, llcp_sock->ssap);
758761
nfc_llcp_local_put(llcp_sock->local);
762+
llcp_sock->local = NULL;
759763

760764
put_dev:
761765
nfc_put_device(dev);

0 commit comments

Comments
 (0)