lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240307161849.9145-1-hgajjar@de.adit-jv.com>
Date: Thu, 7 Mar 2024 17:18:49 +0100
From: Hardik Gajjar <hgajjar@...adit-jv.com>
To: <gregkh@...uxfoundation.org>, <quic_kriskura@...cinc.com>,
	<maze@...gle.com>, <quic_linyyuan@...cinc.com>
CC: <linux-usb@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<guofeng.li@...com>, <hardik.gajjar@...ch.com>, <eugeniu.rosca@...ch.com>
Subject: [PATCH] usb: gadget: f_ncm: Fix Kernel Panic due to access of invalid gadget ptr

In the scenario where the system enters suspend to RAM mode (STR) triggers
the disconnection of Dual Role USB Hub, and the UDC platform driver calls
usb_del_gadget_udc() to cleanup and delete the associated gadget.

However, at this point, the usb0 interface is not yet deleted, leading to
a race condition with the TCP/IP stack attempting to access the network
device parent (gadget pointer), through operations like the GETLINK net
message.

This patch addresses the issue by clearing the netdevice's parent device
pointer when the ncm unbinds, effectively preventing the race condition
during this critical phase.

Followinfg is the backtrace of such race condition
[ 3566.105792] Call trace:
[ 3566.105984] if_nlmsg_size+0x48/0x3b0
[ 3566.107497] rtnetlink_rcv_msg+0x1cc/0x408
[ 3566.107905] netlink_rcv_skb+0x12c/0x164
[ 3566.108264] rtnetlink_rcv+0x18/0x24
[ 3566.108851] netlink_unicast_kernel+0xc4/0x14c
[ 3566.109192] netlink_unicast+0x210/0x2b0
[ 3566.109606] netlink_sendmsg+0x2ec/0x360
[ 3566.110046] __sys_sendto+0x1b8/0x25c
[ 3566.111594] __arm64_sys_sendto+0x28/0x38
[ 3566.112599] el0_svc_common+0xb4/0x19c
[ 3566.112978] el0_svc_handler+0x74/0x98
[ 3566.113269] el0_svc+0x8/0xc

- code: if_nlmsg_size call the following function

static inline int rtnl_vfinfo_size(const struct net_device *dev,
				   u32 ext_filter_mask)
{
	// dev->dev.parent is not NULL
	if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF)) {
		// dev_num_vf use the dev->dev.parent->bus lead to kernel panic.
		int num_vfs = dev_num_vf(dev->dev.parent);
		size_t size = nla_total_size(0);
		size += num_vfs *
			(nla_total_size(0) +
			 nla_total_size(sizeof(struct ifla_vf_mac)) +
			 nla_total_size(sizeof(struct ifla_vf_vlan)) +
			 nla_total_size(0) + /* nest IFLA_VF_VLAN_LIST *

Signed-off-by: Hardik Gajjar <hgajjar@...adit-jv.com>
---
 drivers/usb/gadget/function/f_ncm.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index e2a059cfda2c..fdfb5b3460c7 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -1728,9 +1728,12 @@ static void ncm_free(struct usb_function *f)
 static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct f_ncm *ncm = func_to_ncm(f);
+	struct f_ncm_opts   *ncm_opts;
 
 	DBG(c->cdev, "ncm unbind\n");
 
+	ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst);
+
 	hrtimer_cancel(&ncm->task_timer);
 
 	kfree(f->os_desc_table);
@@ -1746,6 +1749,10 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f)
 
 	kfree(ncm->notify_req->buf);
 	usb_ep_free_request(ncm->notify, ncm->notify_req);
+
+	mutex_lock(&ncm_opts->lock);
+	SET_NETDEV_DEV(ncm_opts->net, NULL);
+	mutex_unlock(&ncm_opts->lock);
 }
 
 static struct usb_function *ncm_alloc(struct usb_function_instance *fi)
-- 
2.17.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ