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>] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 9 Sep 2021 11:46:08 +0800
From:   Zenghui Yu <yuzenghui@...wei.com>
To:     <linux-scsi@...r.kernel.org>, <linux-block@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>
CC:     <fujita.tomonori@....ntt.co.jp>, <axboe@...nel.dk>,
        <martin.petersen@...cle.com>, <hch@....de>,
        <gregkh@...uxfoundation.org>, <wanghaibin.wang@...wei.com>,
        Zenghui Yu <yuzenghui@...wei.com>
Subject: [PATCH] scsi: bsg: Fix device unregistration

We use device_initialize() to take refcount for the device but forget to
put_device() on device teardown, which ends up leaking private data of the
driver core, dev_name(), etc. This is reported by kmemleak at boot time if
we compile kernel with DEBUG_TEST_DRIVER_REMOVE.

Note that adding the missing put_device() is _not_ sufficient to fix device
unregistration. As we don't provide the .release() method for device, which
turned out to be typically wrong and will be complained loudly by the
driver core.

Fix both of them.

Fixes: ead09dd3aed5 ("scsi: bsg: Simplify device registration")
Signed-off-by: Zenghui Yu <yuzenghui@...wei.com>
---
 block/bsg.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 351095193788..c3bb92b9af7e 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -165,13 +165,20 @@ static const struct file_operations bsg_fops = {
 	.llseek		=	default_llseek,
 };
 
+static void bsg_device_release(struct device *dev)
+{
+	struct bsg_device *bd = container_of(dev, struct bsg_device, device);
+
+	ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt));
+	kfree(bd);
+}
+
 void bsg_unregister_queue(struct bsg_device *bd)
 {
 	if (bd->queue->kobj.sd)
 		sysfs_remove_link(&bd->queue->kobj, "bsg");
 	cdev_device_del(&bd->cdev, &bd->device);
-	ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt));
-	kfree(bd);
+	put_device(&bd->device);
 }
 EXPORT_SYMBOL_GPL(bsg_unregister_queue);
 
@@ -198,6 +205,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q,
 	bd->device.devt = MKDEV(bsg_major, ret);
 	bd->device.class = bsg_class;
 	bd->device.parent = parent;
+	bd->device.release = bsg_device_release;
 	dev_set_name(&bd->device, "%s", name);
 	device_initialize(&bd->device);
 
@@ -218,6 +226,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q,
 out_device_del:
 	cdev_device_del(&bd->cdev, &bd->device);
 out_ida_remove:
+	put_device(&bd->device);
 	ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt));
 out_kfree:
 	kfree(bd);
-- 
2.19.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ