|
Takashi Iwai |
577df8 |
From c61760e6940dd4039a7f5e84a6afc9cdbf4d82b6 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
577df8 |
From: Or Cohen <orcohen@paloaltonetworks.com>
|
|
Takashi Iwai |
577df8 |
Date: Tue, 4 May 2021 10:16:46 +0300
|
|
Takashi Iwai |
577df8 |
Subject: [PATCH] net/nfc: fix use-after-free llcp_sock_bind/connect
|
|
Takashi Iwai |
577df8 |
Git-commit: c61760e6940dd4039a7f5e84a6afc9cdbf4d82b6
|
|
Takashi Iwai |
577df8 |
Patch-mainline: v5.13-rc1
|
|
Takashi Iwai |
577df8 |
References: CVE-2021-23134 bsc#1186060
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
Commits 8a4cd82d ("nfc: fix refcount leak in llcp_sock_connect()")
|
|
Takashi Iwai |
577df8 |
and c33b1cc62 ("nfc: fix refcount leak in llcp_sock_bind()")
|
|
Takashi Iwai |
577df8 |
fixed a refcount leak bug in bind/connect but introduced a
|
|
Takashi Iwai |
577df8 |
use-after-free if the same local is assigned to 2 different sockets.
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
This can be triggered by the following simple program:
|
|
Takashi Iwai |
577df8 |
int sock1 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP );
|
|
Takashi Iwai |
577df8 |
int sock2 = socket( AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP );
|
|
Takashi Iwai |
577df8 |
memset( &addr, 0, sizeof(struct sockaddr_nfc_llcp) );
|
|
Takashi Iwai |
577df8 |
addr.sa_family = AF_NFC;
|
|
Takashi Iwai |
577df8 |
addr.nfc_protocol = NFC_PROTO_NFC_DEP;
|
|
Takashi Iwai |
577df8 |
bind( sock1, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) )
|
|
Takashi Iwai |
577df8 |
bind( sock2, (struct sockaddr*) &addr, sizeof(struct sockaddr_nfc_llcp) )
|
|
Takashi Iwai |
577df8 |
close(sock1);
|
|
Takashi Iwai |
577df8 |
close(sock2);
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
Fix this by assigning NULL to llcp_sock->local after calling
|
|
Takashi Iwai |
577df8 |
nfc_llcp_local_put.
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
This addresses CVE-2021-23134.
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
Reported-by: Or Cohen <orcohen@paloaltonetworks.com>
|
|
Takashi Iwai |
577df8 |
Reported-by: Nadav Markus <nmarkus@paloaltonetworks.com>
|
|
Takashi Iwai |
577df8 |
Fixes: c33b1cc62 ("nfc: fix refcount leak in llcp_sock_bind()")
|
|
Takashi Iwai |
577df8 |
Signed-off-by: Or Cohen <orcohen@paloaltonetworks.com>
|
|
Takashi Iwai |
577df8 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Takashi Iwai |
577df8 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
---
|
|
Takashi Iwai |
577df8 |
net/nfc/llcp_sock.c | 4 ++++
|
|
Takashi Iwai |
577df8 |
1 file changed, 4 insertions(+)
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
--- a/net/nfc/llcp_sock.c
|
|
Takashi Iwai |
577df8 |
+++ b/net/nfc/llcp_sock.c
|
|
Takashi Iwai |
577df8 |
@@ -121,12 +121,14 @@ static int llcp_sock_bind(struct socket
|
|
Takashi Iwai |
577df8 |
GFP_KERNEL);
|
|
Takashi Iwai |
577df8 |
if (!llcp_sock->service_name) {
|
|
Takashi Iwai |
577df8 |
nfc_llcp_local_put(llcp_sock->local);
|
|
Takashi Iwai |
577df8 |
+ llcp_sock->local = NULL;
|
|
Takashi Iwai |
577df8 |
ret = -ENOMEM;
|
|
Takashi Iwai |
577df8 |
goto put_dev;
|
|
Takashi Iwai |
577df8 |
}
|
|
Takashi Iwai |
577df8 |
llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock);
|
|
Takashi Iwai |
577df8 |
if (llcp_sock->ssap == LLCP_SAP_MAX) {
|
|
Takashi Iwai |
577df8 |
nfc_llcp_local_put(llcp_sock->local);
|
|
Takashi Iwai |
577df8 |
+ llcp_sock->local = NULL;
|
|
Takashi Iwai |
577df8 |
kfree(llcp_sock->service_name);
|
|
Takashi Iwai |
577df8 |
llcp_sock->service_name = NULL;
|
|
Takashi Iwai |
577df8 |
ret = -EADDRINUSE;
|
|
Takashi Iwai |
577df8 |
@@ -722,6 +724,7 @@ static int llcp_sock_connect(struct sock
|
|
Takashi Iwai |
577df8 |
llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
|
|
Takashi Iwai |
577df8 |
if (llcp_sock->ssap == LLCP_SAP_MAX) {
|
|
Takashi Iwai |
577df8 |
nfc_llcp_local_put(llcp_sock->local);
|
|
Takashi Iwai |
577df8 |
+ llcp_sock->local = NULL;
|
|
Takashi Iwai |
577df8 |
ret = -ENOMEM;
|
|
Takashi Iwai |
577df8 |
goto put_dev;
|
|
Takashi Iwai |
577df8 |
}
|
|
Takashi Iwai |
577df8 |
@@ -765,6 +768,7 @@ sock_unlink:
|
|
Takashi Iwai |
577df8 |
llcp_sock->service_name = NULL;
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
nfc_llcp_local_put(llcp_sock->local);
|
|
Takashi Iwai |
577df8 |
+ llcp_sock->local = NULL;
|
|
Takashi Iwai |
577df8 |
|
|
Takashi Iwai |
577df8 |
put_dev:
|
|
Takashi Iwai |
577df8 |
nfc_put_device(dev);
|