Subject: CVE-2023-1851: nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to llcp_local

From: Greg Kroah-Hartman <[email-masked]>

Description
===========

nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to llcp_local

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.

The Linux kernel CVE team has assigned CVE-2023-1851 to this issue.

Affected and fixed versions
===========================

	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 4.14.336 with commit 83724831dab1
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 4.19.305 with commit df02150025a3
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 5.4.267 with commit 65c6ef02ff26
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 5.10.208 with commit 6adeb15cb6ad
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 5.15.147 with commit 802af3c88ad1
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 6.1.72 with commit a4b0a9b80a96
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 6.6.11 with commit fb195df90544
	Issue introduced in 3.6 with commit c7aa12252f51 and fixed in 6.7 with commit c95f919567d6

Please see https://www.kernel.org or a full list of currently supported
kernel versions by the kernel community.

Unaffected versions might change over time as fixes are backported to
older supported kernel versions.  The official CVE entry at
	https://cve.org/CVERecord/?id=CVE-2023-1851
will be updated if fixes are backported, please check that for the most
up to date information about this issue.

Affected files
==============

The file(s) affected by this issue are:
	net/nfc/llcp_core.c

Mitigation
==========

The Linux kernel CVE team recommends that you update to the latest
stable kernel version for this, and many other bugfixes.  Individual
changes are never tested alone, but rather are part of a larger kernel
release.  Cherry-picking individual commits is not recommended or
supported by the Linux kernel community at all.  If however, updating to
the latest release is impossible, the individual changes to resolve this
issue can be found at these commits:
	https://git.kernel.org/stable/c/83724831dab1
	https://git.kernel.org/stable/c/df02150025a3
	https://git.kernel.org/stable/c/65c6ef02ff26
	https://git.kernel.org/stable/c/6adeb15cb6ad
	https://git.kernel.org/stable/c/802af3c88ad1
	https://git.kernel.org/stable/c/a4b0a9b80a96
	https://git.kernel.org/stable/c/fb195df90544
	https://git.kernel.org/stable/c/c95f919567d6