public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Suman Ghosh <sumang@marvell.com>,
	Siddh Raman Pant <code@siddh.me>,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
	"David S. Miller" <davem@davemloft.net>,
	Sasha Levin <sashal@kernel.org>,
	syzbot+bbe84a4010eeea00982d@syzkaller.appspotmail.com
Subject: [PATCH 4.19 01/25] nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to llcp_local
Date: Sat, 13 Jan 2024 10:49:42 +0100	[thread overview]
Message-ID: <20240113094205.078669942@linuxfoundation.org> (raw)
In-Reply-To: <20240113094205.025407355@linuxfoundation.org>

4.19-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Siddh Raman Pant <code@siddh.me>

[ Upstream commit c95f919567d6f1914f13350af61a1b044ac85014 ]

llcp_sock_sendmsg() calls nfc_llcp_send_ui_frame() which in turn calls
nfc_alloc_send_skb(), which accesses the nfc_dev from the llcp_sock for
getting the headroom and tailroom needed for skb allocation.

Parallelly the nfc_dev can be freed, as the refcount is decreased via
nfc_free_device(), leading to a UAF reported by Syzkaller, which can
be summarized as follows:

(1) llcp_sock_sendmsg() -> nfc_llcp_send_ui_frame()
	-> nfc_alloc_send_skb() -> Dereference *nfc_dev
(2) virtual_ncidev_close() -> nci_free_device() -> nfc_free_device()
	-> put_device() -> nfc_release() -> Free *nfc_dev

When a reference to llcp_local is acquired, we do not acquire the same
for the nfc_dev. This leads to freeing even when the llcp_local is in
use, and this is the case with the UAF described above too.

Thus, when we acquire a reference to llcp_local, we should acquire a
reference to nfc_dev, and release the references appropriately later.

References for llcp_local is initialized in nfc_llcp_register_device()
(which is called by nfc_register_device()). Thus, we should acquire a
reference to nfc_dev there.

nfc_unregister_device() calls nfc_llcp_unregister_device() which in
turn calls nfc_llcp_local_put(). Thus, the reference to nfc_dev is
appropriately released later.

Reported-and-tested-by: syzbot+bbe84a4010eeea00982d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=bbe84a4010eeea00982d
Fixes: c7aa12252f51 ("NFC: Take a reference on the LLCP local pointer when creating a socket")
Reviewed-by: Suman Ghosh <sumang@marvell.com>
Signed-off-by: Siddh Raman Pant <code@siddh.me>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp_core.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index c30b28465e644..a217830f0f34c 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -157,6 +157,13 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
 
 struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
 {
+	/* Since using nfc_llcp_local may result in usage of nfc_dev, whenever
+	 * we hold a reference to local, we also need to hold a reference to
+	 * the device to avoid UAF.
+	 */
+	if (!nfc_get_device(local->dev->idx))
+		return NULL;
+
 	kref_get(&local->ref);
 
 	return local;
@@ -190,10 +197,18 @@ static void local_release(struct kref *ref)
 
 int nfc_llcp_local_put(struct nfc_llcp_local *local)
 {
+	struct nfc_dev *dev;
+	int ret;
+
 	if (local == NULL)
 		return 0;
 
-	return kref_put(&local->ref, local_release);
+	dev = local->dev;
+
+	ret = kref_put(&local->ref, local_release);
+	nfc_put_device(dev);
+
+	return ret;
 }
 
 static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
@@ -951,8 +966,17 @@ static void nfc_llcp_recv_connect(struct nfc_llcp_local *local,
 	}
 
 	new_sock = nfc_llcp_sock(new_sk);
-	new_sock->dev = local->dev;
+
 	new_sock->local = nfc_llcp_local_get(local);
+	if (!new_sock->local) {
+		reason = LLCP_DM_REJ;
+		sock_put(&new_sock->sk);
+		release_sock(&sock->sk);
+		sock_put(&sock->sk);
+		goto fail;
+	}
+
+	new_sock->dev = local->dev;
 	new_sock->rw = sock->rw;
 	new_sock->miux = sock->miux;
 	new_sock->nfc_protocol = sock->nfc_protocol;
@@ -1584,7 +1608,16 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
 	if (local == NULL)
 		return -ENOMEM;
 
-	local->dev = ndev;
+	/* As we are going to initialize local's refcount, we need to get the
+	 * nfc_dev to avoid UAF, otherwise there is no point in continuing.
+	 * See nfc_llcp_local_get().
+	 */
+	local->dev = nfc_get_device(ndev->idx);
+	if (!local->dev) {
+		kfree(local);
+		return -ENODEV;
+	}
+
 	INIT_LIST_HEAD(&local->list);
 	kref_init(&local->ref);
 	mutex_init(&local->sdp_lock);
-- 
2.43.0




  reply	other threads:[~2024-01-13  9:54 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-13  9:49 [PATCH 4.19 00/25] 4.19.305-rc1 review Greg Kroah-Hartman
2024-01-13  9:49 ` Greg Kroah-Hartman [this message]
2024-01-13  9:49 ` [PATCH 4.19 02/25] i40e: Fix filter input checks to prevent config with invalid values Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 03/25] net: sched: em_text: fix possible memory leak in em_text_destroy() Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 04/25] ARM: sun9i: smp: Fix array-index-out-of-bounds read in sunxi_mc_smp_init Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 05/25] net: bcmgenet: Fix FCS generation for fragmented skbuffs Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 06/25] net: Save and restore msg_namelen in sock_sendmsg Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 07/25] i40e: fix use-after-free in i40e_aqc_add_filters() Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 08/25] i40e: Restore VF MSI-X state during PCI reset Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 09/25] net/qla3xxx: switch from pci_ to dma_ API Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 10/25] net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 11/25] asix: Add check for usbnet_get_endpoints Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 12/25] bnxt_en: Remove mis-applied code from bnxt_cfg_ntp_filters() Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 13/25] mm/memory-failure: check the mapcount of the precise page Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 14/25] firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and ASM108x/VT630x PCIe cards Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 15/25] mm: fix unmap_mapping_range high bits shift bug Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 16/25] mmc: rpmb: fixes pause retune on all RPMB partitions Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 17/25] mmc: core: Cancel delayed work before releasing host Greg Kroah-Hartman
2024-01-13  9:49 ` [PATCH 4.19 18/25] fuse: nlookup missing decrement in fuse_direntplus_link Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 19/25] netfilter: nf_tables: Reject tables of unsupported family Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 20/25] PCI: Extract ATS disabling to a helper function Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 21/25] PCI: Disable ATS for specific Intel IPU E2000 devices Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 22/25] net: add a route cache full diagnostic message Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 23/25] net/dst: use a smaller percpu_counter batch for dst entries accounting Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 24/25] ipv6: make ip6_rt_gc_expire an atomic_t Greg Kroah-Hartman
2024-01-13  9:50 ` [PATCH 4.19 25/25] ipv6: remove max_size check inline with ipv4 Greg Kroah-Hartman
2024-01-14 10:32 ` [PATCH 4.19 00/25] 4.19.305-rc1 review Pavel Machek
2024-01-15  8:57 ` Naresh Kamboju
2024-01-15 10:23 ` Jon Hunter
2024-01-15 16:24 ` Harshit Mogalapalli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240113094205.078669942@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=code@siddh.me \
    --cc=davem@davemloft.net \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=sumang@marvell.com \
    --cc=syzbot+bbe84a4010eeea00982d@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox