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 for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250616165321.4130714-1-dmantipov@yandex.ru>
Date: Mon, 16 Jun 2025 19:53:21 +0300
From: Dmitry Antipov <dmantipov@...dex.ru>
To: Parthiban Veerasooran <parthiban.veerasooran@...rochip.com>,
	Christian Gromm <christian.gromm@...rochip.com>
Cc: linux-kernel@...r.kernel.org,
	lvc-project@...uxtesting.org,
	Dmitry Antipov <dmantipov@...dex.ru>
Subject: [PATCH] most: core, usb: fix generic device management

Syzkaller reports [1, 2] refcount and use-after-free errors for
the generic 'struct device' data used here and there. An overall
usage of the generic device is somewhat confusing because the
same device instance is shared between 'struct most_dev' and
'struct most_interface' instances and as a parent of the device
embedded into 'struct most_dci_obj' instance pointed from the
former. This patch hopefully fixes both of the known issues
assumes the following:

1. Direct 'mdev->iface.dev = &mdev->dev' assignment performed in
   'hdm_probe()' is wrong and 'get_device()' should be used to
   not break an internal reference counting.
2. To use 'get_device()' in the code above, an underlying device
   should be properly initialized with 'device_initialize()'. So
   'most_register_interface()' should use 'device_add()' rather
   than 'device_register()'.
3. In 'hdm_disconnect()', 'put_device(&mdev->dci->dev)' is wrong
   because it's done from 'device_unregister(&mdev->dci->dev)'
   called from the above.

[1] https://syzkaller.appspot.com/bug?extid=d175ca7205b4f18390b1
[2] https://syzkaller.appspot.com/bug?extid=916742d5d24f6c254761

Signed-off-by: Dmitry Antipov <dmantipov@...dex.ru>
---
 drivers/most/core.c     |  2 +-
 drivers/most/most_usb.c | 11 ++++++-----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/most/core.c b/drivers/most/core.c
index a635d5082ebb..10951171e72d 100644
--- a/drivers/most/core.c
+++ b/drivers/most/core.c
@@ -1304,7 +1304,7 @@ int most_register_interface(struct most_interface *iface)
 	iface->dev->bus = &mostbus;
 	iface->dev->groups = interface_attr_groups;
 	dev_set_drvdata(iface->dev, iface);
-	if (device_register(iface->dev)) {
+	if (device_add(iface->dev)) {
 		dev_err(iface->dev, "Failed to register interface device\n");
 		kfree(iface->p);
 		put_device(iface->dev);
diff --git a/drivers/most/most_usb.c b/drivers/most/most_usb.c
index cf5be9c449a5..3ee7abd15a09 100644
--- a/drivers/most/most_usb.c
+++ b/drivers/most/most_usb.c
@@ -973,8 +973,13 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 	mdev->usb_device = usb_dev;
 	mdev->link_stat_timer.expires = jiffies + (2 * HZ);
 
+	device_initialize(&mdev->dev);
+	mdev->dev.init_name = mdev->description;
+	mdev->dev.parent = &interface->dev;
+	mdev->dev.release = release_mdev;
+
 	mdev->iface.mod = hdm_usb_fops.owner;
-	mdev->iface.dev = &mdev->dev;
+	mdev->iface.dev = get_device(&mdev->dev);
 	mdev->iface.driver_dev = &interface->dev;
 	mdev->iface.interface = ITYPE_USB;
 	mdev->iface.configure = hdm_configure_channel;
@@ -993,9 +998,6 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 		 usb_dev->config->desc.bConfigurationValue,
 		 usb_iface_desc->desc.bInterfaceNumber);
 
-	mdev->dev.init_name = mdev->description;
-	mdev->dev.parent = &interface->dev;
-	mdev->dev.release = release_mdev;
 	mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
 	if (!mdev->conf)
 		goto err_free_mdev;
@@ -1126,7 +1128,6 @@ static void hdm_disconnect(struct usb_interface *interface)
 	kfree(mdev->cap);
 	kfree(mdev->conf);
 	kfree(mdev->ep_address);
-	put_device(&mdev->dci->dev);
 	put_device(&mdev->dev);
 }
 
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ