linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] scsi: bsg: Fix device unregistration
@ 2021-09-09  3:46 Zenghui Yu
  2021-09-09  5:22 ` Christoph Hellwig
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Zenghui Yu @ 2021-09-09  3:46 UTC (permalink / raw)
  To: linux-scsi, linux-block, linux-kernel
  Cc: fujita.tomonori, axboe, martin.petersen, hch, gregkh,
	wanghaibin.wang, Zenghui Yu

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@huawei.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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09  3:46 [PATCH] scsi: bsg: Fix device unregistration Zenghui Yu
@ 2021-09-09  5:22 ` Christoph Hellwig
  2021-09-09  5:36 ` Greg KH
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2021-09-09  5:22 UTC (permalink / raw)
  To: Zenghui Yu
  Cc: linux-scsi, linux-block, linux-kernel, fujita.tomonori, axboe,
	martin.petersen, hch, gregkh, wanghaibin.wang

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09  3:46 [PATCH] scsi: bsg: Fix device unregistration Zenghui Yu
  2021-09-09  5:22 ` Christoph Hellwig
@ 2021-09-09  5:36 ` Greg KH
  2021-09-09 20:40 ` Jens Axboe
  2021-09-10 12:45 ` Johan Hovold
  3 siblings, 0 replies; 10+ messages in thread
From: Greg KH @ 2021-09-09  5:36 UTC (permalink / raw)
  To: Zenghui Yu
  Cc: linux-scsi, linux-block, linux-kernel, fujita.tomonori, axboe,
	martin.petersen, hch, wanghaibin.wang

On Thu, Sep 09, 2021 at 11:46:08AM +0800, Zenghui Yu wrote:
> 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@huawei.com>
> ---
>  block/bsg.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09  3:46 [PATCH] scsi: bsg: Fix device unregistration Zenghui Yu
  2021-09-09  5:22 ` Christoph Hellwig
  2021-09-09  5:36 ` Greg KH
@ 2021-09-09 20:40 ` Jens Axboe
  2021-09-09 20:42   ` Jens Axboe
  2021-09-10 12:45 ` Johan Hovold
  3 siblings, 1 reply; 10+ messages in thread
From: Jens Axboe @ 2021-09-09 20:40 UTC (permalink / raw)
  To: Zenghui Yu, linux-scsi, linux-block, linux-kernel
  Cc: fujita.tomonori, martin.petersen, hch, gregkh, wanghaibin.wang

On 9/8/21 9:46 PM, Zenghui Yu wrote:
> 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.

Applied, thanks.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09 20:40 ` Jens Axboe
@ 2021-09-09 20:42   ` Jens Axboe
  2021-09-10  1:28     ` Martin K. Petersen
  2021-09-10  7:38     ` Christoph Hellwig
  0 siblings, 2 replies; 10+ messages in thread
From: Jens Axboe @ 2021-09-09 20:42 UTC (permalink / raw)
  To: Zenghui Yu, linux-scsi, linux-block, linux-kernel
  Cc: fujita.tomonori, martin.petersen, hch, gregkh, wanghaibin.wang

On 9/9/21 2:40 PM, Jens Axboe wrote:
> On 9/8/21 9:46 PM, Zenghui Yu wrote:
>> 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.
> 
> Applied, thanks.

Actually, let's move this through the SCSI tree, as the offending patch
went that way (and my branches are behind that point).

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09 20:42   ` Jens Axboe
@ 2021-09-10  1:28     ` Martin K. Petersen
  2021-09-10  7:38     ` Christoph Hellwig
  1 sibling, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2021-09-10  1:28 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Zenghui Yu, linux-scsi, linux-block, linux-kernel,
	fujita.tomonori, martin.petersen, hch, gregkh, wanghaibin.wang


Jens,

> Actually, let's move this through the SCSI tree, as the offending
> patch went that way (and my branches are behind that point).

Sure. I queued it up...

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09 20:42   ` Jens Axboe
  2021-09-10  1:28     ` Martin K. Petersen
@ 2021-09-10  7:38     ` Christoph Hellwig
  1 sibling, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2021-09-10  7:38 UTC (permalink / raw)
  To: Jens Axboe
  Cc: Zenghui Yu, linux-scsi, linux-block, linux-kernel,
	fujita.tomonori, martin.petersen, hch, gregkh, wanghaibin.wang

On Thu, Sep 09, 2021 at 02:42:10PM -0600, Jens Axboe wrote:
> Actually, let's move this through the SCSI tree, as the offending patch
> went that way (and my branches are behind that point).

Btw, should we move bsg.c and bsg-lib.c to drivers/scsi/?  They very much
are SCSI infrastructure now.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-09  3:46 [PATCH] scsi: bsg: Fix device unregistration Zenghui Yu
                   ` (2 preceding siblings ...)
  2021-09-09 20:40 ` Jens Axboe
@ 2021-09-10 12:45 ` Johan Hovold
  2021-09-10 16:50   ` Martin K. Petersen
  2021-09-11  1:41   ` Zenghui Yu
  3 siblings, 2 replies; 10+ messages in thread
From: Johan Hovold @ 2021-09-10 12:45 UTC (permalink / raw)
  To: Zenghui Yu
  Cc: linux-scsi, linux-block, linux-kernel, fujita.tomonori, axboe,
	martin.petersen, hch, gregkh, wanghaibin.wang

On Thu, Sep 09, 2021 at 11:46:08AM +0800, Zenghui Yu wrote:
> 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@huawei.com>
> ---
>  block/bsg.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
 
> +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);
> +}

> @@ -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);

Ehh, what about the blatant use-after-free and double-free you just
added here?

Martin, can this still be dropped from the scsi tree or does it need to
be fixed incrementally?

Johan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-10 12:45 ` Johan Hovold
@ 2021-09-10 16:50   ` Martin K. Petersen
  2021-09-11  1:41   ` Zenghui Yu
  1 sibling, 0 replies; 10+ messages in thread
From: Martin K. Petersen @ 2021-09-10 16:50 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Zenghui Yu, linux-scsi, linux-block, linux-kernel,
	fujita.tomonori, axboe, martin.petersen, hch, gregkh,
	wanghaibin.wang


Johan,

> Martin, can this still be dropped from the scsi tree or does it need to
> be fixed incrementally?

I dropped it.

Zenghui: Please fix.

-- 
Martin K. Petersen	Oracle Linux Engineering

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] scsi: bsg: Fix device unregistration
  2021-09-10 12:45 ` Johan Hovold
  2021-09-10 16:50   ` Martin K. Petersen
@ 2021-09-11  1:41   ` Zenghui Yu
  1 sibling, 0 replies; 10+ messages in thread
From: Zenghui Yu @ 2021-09-11  1:41 UTC (permalink / raw)
  To: Johan Hovold
  Cc: linux-scsi, linux-block, linux-kernel, fujita.tomonori, axboe,
	martin.petersen, hch, gregkh, wanghaibin.wang

On 2021/9/10 20:45, Johan Hovold wrote:
> On Thu, Sep 09, 2021 at 11:46:08AM +0800, Zenghui Yu wrote:

>> @@ -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);
> 
> Ehh, what about the blatant use-after-free and double-free you just
> added here?

Yeah, whoops. That's definitely wrong. I'm squash the following fix
in this patch.

Thanks for the heads up!

|diff --git a/block/bsg.c b/block/bsg.c
|index c3bb92b9af7e..882f56bff14f 100644
|--- a/block/bsg.c
|+++ b/block/bsg.c
|@@ -200,7 +200,8 @@ struct bsg_device *bsg_register_queue(struct 
request_queue *q,
|        if (ret < 0) {
|                if (ret == -ENOSPC)
|                        dev_err(parent, "bsg: too many bsg devices\n");
|-               goto out_kfree;
|+               kfree(bd);
|+               return ERR_PTR(ret);
|        }
|        bd->device.devt = MKDEV(bsg_major, ret);
|        bd->device.class = bsg_class;
|@@ -213,7 +214,7 @@ struct bsg_device *bsg_register_queue(struct 
request_queue *q,
|        bd->cdev.owner = THIS_MODULE;
|        ret = cdev_device_add(&bd->cdev, &bd->device);
|        if (ret)
|-               goto out_ida_remove;
|+               goto out_put_device;
|
|        if (q->kobj.sd) {
|                ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg");
|@@ -225,11 +226,8 @@ struct bsg_device *bsg_register_queue(struct 
request_queue *q,
|
| out_device_del:
|        cdev_device_del(&bd->cdev, &bd->device);
|-out_ida_remove:
|+out_put_device:
|        put_device(&bd->device);
|-       ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt));
|-out_kfree:
|-       kfree(bd);
|        return ERR_PTR(ret);
| }
| EXPORT_SYMBOL_GPL(bsg_register_queue);

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-09-11  1:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-09  3:46 [PATCH] scsi: bsg: Fix device unregistration Zenghui Yu
2021-09-09  5:22 ` Christoph Hellwig
2021-09-09  5:36 ` Greg KH
2021-09-09 20:40 ` Jens Axboe
2021-09-09 20:42   ` Jens Axboe
2021-09-10  1:28     ` Martin K. Petersen
2021-09-10  7:38     ` Christoph Hellwig
2021-09-10 12:45 ` Johan Hovold
2021-09-10 16:50   ` Martin K. Petersen
2021-09-11  1:41   ` Zenghui Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).