diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2021-09-16 11:34:58 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-10-02 11:16:23 +0200 |
commit | 1c8625aac0d204e567fcee5a8b4e9d0145f011c0 (patch) | |
tree | d02216c2b2e22f9a8817dc2e016636e397c33e9d /drivers/block | |
parent | 41023724b2b09ec1c8555bb32c929a82ebc84359 (diff) | |
download | barebox-1c8625aac0d204e567fcee5a8b4e9d0145f011c0.tar.gz barebox-1c8625aac0d204e567fcee5a8b4e9d0145f011c0.tar.xz |
virtio: implement remove callbacks
virtio parent device drivers (e.g. PCI and MMIO) create child devices
and free them on remove. The virtio drivers for the child devices (e.g.
block and console) however don't unregister with their respective
subsystems in the remove callbacks. So these subsystems may have stale
pointers pointing at removed devices. This is especially problematic for
the console driver, because the virtio console device_d will be removed,
but the console itself remains registered leading to a use-after-free
as soon as printf is invoked for the previously active console.
This leads to a crash when typing reset in
https://www.barebox.org/jsbarebox/?graphic=0
Fix this for all virtio drivers.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20210916093458.21102-1-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b7a83cf686..87ab505f83 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -95,6 +95,7 @@ static int virtio_blk_probe(struct virtio_device *vdev) return ret; priv->vdev = vdev; + vdev->priv = priv; devnum = cdev_find_free_index("virtioblk"); priv->blk.cdev.name = xasprintf("virtioblk%d", devnum); @@ -115,8 +116,13 @@ static int virtio_blk_probe(struct virtio_device *vdev) static void virtio_blk_remove(struct virtio_device *vdev) { + struct virtio_blk_priv *priv = vdev->priv; + vdev->config->reset(vdev); + blockdevice_unregister(&priv->blk); vdev->config->del_vqs(vdev); + + free(priv); } static const struct virtio_device_id id_table[] = { |