Skip to content

Commit fab7f25

Browse files
heynemaxmstsirkin
authored andcommitted
virtio-mmio: fix memory leak of vm_dev
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: [email protected] Fixes: 55c91fe ("virtio-mmio: don't break lifecycle of vm_dev") Signed-off-by: Maximilian Heyne <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Tested-by: Catalin Marinas <[email protected]> Reviewed-by: Xuan Zhuo <[email protected]> Message-Id: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Reviewed-by: Wolfram Sang <[email protected]>
1 parent d121df7 commit fab7f25

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

drivers/virtio/virtio_mmio.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -631,22 +631,26 @@ static int virtio_mmio_probe(struct platform_device *pdev)
631631
spin_lock_init(&vm_dev->lock);
632632

633633
vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
634-
if (IS_ERR(vm_dev->base))
635-
return PTR_ERR(vm_dev->base);
634+
if (IS_ERR(vm_dev->base)) {
635+
rc = PTR_ERR(vm_dev->base);
636+
goto free_vm_dev;
637+
}
636638

637639
/* Check magic value */
638640
magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
639641
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
640642
dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic);
641-
return -ENODEV;
643+
rc = -ENODEV;
644+
goto free_vm_dev;
642645
}
643646

644647
/* Check device version */
645648
vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION);
646649
if (vm_dev->version < 1 || vm_dev->version > 2) {
647650
dev_err(&pdev->dev, "Version %ld not supported!\n",
648651
vm_dev->version);
649-
return -ENXIO;
652+
rc = -ENXIO;
653+
goto free_vm_dev;
650654
}
651655

652656
vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID);
@@ -655,7 +659,8 @@ static int virtio_mmio_probe(struct platform_device *pdev)
655659
* virtio-mmio device with an ID 0 is a (dummy) placeholder
656660
* with no function. End probing now with no error reported.
657661
*/
658-
return -ENODEV;
662+
rc = -ENODEV;
663+
goto free_vm_dev;
659664
}
660665
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
661666

@@ -685,6 +690,10 @@ static int virtio_mmio_probe(struct platform_device *pdev)
685690
put_device(&vm_dev->vdev.dev);
686691

687692
return rc;
693+
694+
free_vm_dev:
695+
kfree(vm_dev);
696+
return rc;
688697
}
689698

690699
static int virtio_mmio_remove(struct platform_device *pdev)

0 commit comments

Comments
 (0)