* [PATCH] virtio-mmio: fix memory leak of vm_dev
@ 2023-09-05 9:42 Maximilian Heyne
2023-09-06 10:02 ` Maximilian Heyne
2023-09-06 16:26 ` Catalin Marinas
0 siblings, 2 replies; 3+ messages in thread
From: Maximilian Heyne @ 2023-09-05 9:42 UTC (permalink / raw)
Cc: Maximilian Heyne, stable, Michael S. Tsirkin, Jason Wang,
Xuan Zhuo, Wolfram Sang, virtualization, linux-kernel
With the recent removal of vm_dev from devres its memory is only freed
via the callback virtio_mmio_release_dev. However, this only takes
effect after device_add is called by register_virtio_device. Until then
it's an unmanaged resource and must be explicitly freed on error exit.
This bug was discovered and resolved using Coverity Static Analysis
Security Testing (SAST) by Synopsys, Inc.
Cc: stable@vger.kernel.org
Fixes: 55c91fedd03d ("virtio-mmio: don't break lifecycle of vm_dev")
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
Please note that I have only compile tested this code.
drivers/virtio/virtio_mmio.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 97760f611295..b2a48d07e973 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -631,13 +631,16 @@ static int virtio_mmio_probe(struct platform_device *pdev)
spin_lock_init(&vm_dev->lock);
vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(vm_dev->base))
+ if (IS_ERR(vm_dev->base)) {
+ kfree(vm_dev);
return PTR_ERR(vm_dev->base);
+ }
/* Check magic value */
magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
+ kfree(vm_dev);
return -ENODEV;
}
@@ -646,6 +649,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
if (vm_dev->version < 1 || vm_dev->version > 2) {
dev_err(&pdev->dev, "Version %ld not supported!\n",
vm_dev->version);
+ kfree(vm_dev);
return -ENXIO;
}
@@ -655,6 +659,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
* virtio-mmio device with an ID 0 is a (dummy) placeholder
* with no function. End probing now with no error reported.
*/
+ kfree(vm_dev);
return -ENODEV;
}
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
--
2.40.1
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] virtio-mmio: fix memory leak of vm_dev
2023-09-05 9:42 [PATCH] virtio-mmio: fix memory leak of vm_dev Maximilian Heyne
@ 2023-09-06 10:02 ` Maximilian Heyne
2023-09-06 16:26 ` Catalin Marinas
1 sibling, 0 replies; 3+ messages in thread
From: Maximilian Heyne @ 2023-09-06 10:02 UTC (permalink / raw)
To: stable, Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Wolfram Sang,
virtualization, linux-kernel
On Tue, Sep 05, 2023 at 09:42:28AM +0000, Maximilian Heyne wrote:
> With the recent removal of vm_dev from devres its memory is only freed
> via the callback virtio_mmio_release_dev. However, this only takes
> effect after device_add is called by register_virtio_device. Until then
> it's an unmanaged resource and must be explicitly freed on error exit.
>
> This bug was discovered and resolved using Coverity Static Analysis
> Security Testing (SAST) by Synopsys, Inc.
>
> Cc: stable@vger.kernel.org
> Fixes: 55c91fedd03d ("virtio-mmio: don't break lifecycle of vm_dev")
> Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
> ---
> Please note that I have only compile tested this code.
>
> drivers/virtio/virtio_mmio.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index 97760f611295..b2a48d07e973 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -631,13 +631,16 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> spin_lock_init(&vm_dev->lock);
>
> vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
> - if (IS_ERR(vm_dev->base))
> + if (IS_ERR(vm_dev->base)) {
> + kfree(vm_dev);
> return PTR_ERR(vm_dev->base);
I have a use-after-free here. Will send a v2 where this is fixed.
> + }
>
> /* Check magic value */
> magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
> if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
> dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
> + kfree(vm_dev);
> return -ENODEV;
> }
>
> @@ -646,6 +649,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> if (vm_dev->version < 1 || vm_dev->version > 2) {
> dev_err(&pdev->dev, "Version %ld not supported!\n",
> vm_dev->version);
> + kfree(vm_dev);
> return -ENXIO;
> }
>
> @@ -655,6 +659,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> * virtio-mmio device with an ID 0 is a (dummy) placeholder
> * with no function. End probing now with no error reported.
> */
> + kfree(vm_dev);
> return -ENODEV;
> }
> vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
> --
> 2.40.1
>
Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] virtio-mmio: fix memory leak of vm_dev
2023-09-05 9:42 [PATCH] virtio-mmio: fix memory leak of vm_dev Maximilian Heyne
2023-09-06 10:02 ` Maximilian Heyne
@ 2023-09-06 16:26 ` Catalin Marinas
1 sibling, 0 replies; 3+ messages in thread
From: Catalin Marinas @ 2023-09-06 16:26 UTC (permalink / raw)
To: Maximilian Heyne
Cc: stable, Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Wolfram Sang,
virtualization, linux-kernel
On Tue, Sep 05, 2023 at 09:42:28AM +0000, Maximilian Heyne wrote:
> With the recent removal of vm_dev from devres its memory is only freed
> via the callback virtio_mmio_release_dev. However, this only takes
> effect after device_add is called by register_virtio_device. Until then
> it's an unmanaged resource and must be explicitly freed on error exit.
>
> This bug was discovered and resolved using Coverity Static Analysis
> Security Testing (SAST) by Synopsys, Inc.
>
> Cc: stable@vger.kernel.org
> Fixes: 55c91fedd03d ("virtio-mmio: don't break lifecycle of vm_dev")
> Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
Kmemleak was reporting around 31 of these leaks (under qemu). I have not
tried your patch yet as you mentioned a v2.
unreferenced object 0xffff000040bb6c00 (size 1024):
comm "swapper/0", pid 1, jiffies 4294892472 (age 106.728s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000669bb200>] __kmem_cache_alloc_node+0x1c4/0x288
[<00000000ac0129e3>] kmalloc_trace+0x20/0x2c
[<0000000055d7a492>] virtio_mmio_probe+0x28/0x260
[<000000002661dcec>] platform_probe+0x68/0xdc
[<00000000e9abc76a>] really_probe+0x148/0x2ac
[<00000000d9fbd8d5>] __driver_probe_device+0x78/0x12c
[<0000000060d7804a>] driver_probe_device+0x3c/0x15c
[<00000000705fa0e9>] __driver_attach+0x94/0x19c
[<000000005079c97f>] bus_for_each_dev+0x74/0xd4
[<0000000026582009>] driver_attach+0x24/0x30
[<000000003e6b0968>] bus_add_driver+0xe4/0x1e8
[<000000009e7b5554>] driver_register+0x60/0x128
[<00000000d1f180b4>] __platform_driver_register+0x28/0x34
[<0000000097a0072e>] virtio_mmio_init+0x1c/0x28
[<00000000b3340a88>] do_one_initcall+0x6c/0x1b0
[<0000000048f4ff06>] kernel_init_freeable+0x1bc/0x284
> diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
> index 97760f611295..b2a48d07e973 100644
> --- a/drivers/virtio/virtio_mmio.c
> +++ b/drivers/virtio/virtio_mmio.c
> @@ -631,13 +631,16 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> spin_lock_init(&vm_dev->lock);
>
> vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
> - if (IS_ERR(vm_dev->base))
> + if (IS_ERR(vm_dev->base)) {
> + kfree(vm_dev);
> return PTR_ERR(vm_dev->base);
> + }
>
> /* Check magic value */
> magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
> if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
> dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
> + kfree(vm_dev);
> return -ENODEV;
> }
>
> @@ -646,6 +649,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> if (vm_dev->version < 1 || vm_dev->version > 2) {
> dev_err(&pdev->dev, "Version %ld not supported!\n",
> vm_dev->version);
> + kfree(vm_dev);
> return -ENXIO;
> }
>
> @@ -655,6 +659,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
> * virtio-mmio device with an ID 0 is a (dummy) placeholder
> * with no function. End probing now with no error reported.
> */
> + kfree(vm_dev);
> return -ENODEV;
> }
> vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
I'd rather have a goto with a single point of freeing.
--
Catalin
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-09-06 16:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-05 9:42 [PATCH] virtio-mmio: fix memory leak of vm_dev Maximilian Heyne
2023-09-06 10:02 ` Maximilian Heyne
2023-09-06 16:26 ` Catalin Marinas
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).