From 4dbac1aed2ca7e68e9384b0e49750d54d4cbd43d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 30 Nov 2019 20:42:20 +0100 Subject: [PATCH 1/3] net/virtio: Drop useless n->primary_dev not null checks virtio_net_handle_migration_primary() returns early when it can't ensure n->primary_dev is non-null. Checking it again right after that early return is redundant. Drop. If n->primary_dev is null on entering failover_replug_primary(), @pdev will become null, and pdev->partially_hotplugged will crash. Checking n->primary_dev later is useless. It can't actually be null, because its caller virtio_net_handle_migration_primary() ensures it isn't. Drop the useless check. Cc: Jens Freimann Cc: Michael S. Tsirkin Signed-off-by: Markus Armbruster Message-Id: <20191130194240.10517-2-armbru@redhat.com> Reviewed-by: Jens Freimann --- hw/net/virtio-net.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3c31471026..87088ba374 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2810,11 +2810,6 @@ static bool failover_replug_primary(VirtIONet *n, Error **errp) goto out; } } - if (!n->primary_dev) { - error_setg(errp, "virtio_net: couldn't find primary device"); - goto out; - } - n->primary_bus = n->primary_dev->parent_bus; if (!n->primary_bus) { error_setg(errp, "virtio_net: couldn't find primary bus"); @@ -2849,8 +2844,7 @@ static void virtio_net_handle_migration_primary(VirtIONet *n, } } - if (migration_in_setup(s) && !should_be_hidden && - n->primary_dev) { + if (migration_in_setup(s) && !should_be_hidden) { if (failover_unplug_primary(n)) { vmstate_unregister(n->primary_dev, qdev_get_vmsd(n->primary_dev), n->primary_dev); From 5a0948d36c4cbc1c5534afac6fee99de55245d12 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 30 Nov 2019 20:42:21 +0100 Subject: [PATCH 2/3] net/virtio: Fix failover error handling crash bugs Functions that take an Error ** parameter to pass an error to the caller expect the parameter to point to null. failover_replug_primary() violates this precondition in several places: * After qemu_opts_from_qdict() failed, *errp is no longer null. Passing it to error_setg() is wrong, and will trip the assertion in error_setv(). Messed up in commit 150ab54aa6 "net/virtio: fix re-plugging of primary device". Simply drop the error_setg(). * Passing @errp to qemu_opt_set_bool(), hotplug_handler_pre_plug(), and hotplug_handler_plug() is wrong. If one of the first two fails, *errp is no longer null. Risks tripping the same assertion. Moreover, continuing after such errors is unsafe. Messed up in commit 9711cd0dfc "net/virtio: add failover support". Fix by handling each error properly. failover_replug_primary() crashes when passed a null @errp. Also messed up in commit 9711cd0dfc. This bug can't bite as no caller actually passes null. Fix it anyway. Fixes: 9711cd0dfc3fa414f7f64935713c07134ae67971 Fixes: 150ab54aa6934583180f88a2bd540bc6fc4fbff3 Cc: Jens Freimann Cc: Michael S. Tsirkin Signed-off-by: Markus Armbruster Message-Id: <20191130194240.10517-3-armbru@redhat.com> Reviewed-by: Jens Freimann --- hw/net/virtio-net.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 87088ba374..db3d7c38e6 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2795,6 +2795,7 @@ static bool failover_unplug_primary(VirtIONet *n) static bool failover_replug_primary(VirtIONet *n, Error **errp) { + Error *err = NULL; HotplugHandler *hotplug_ctrl; PCIDevice *pdev = PCI_DEVICE(n->primary_dev); @@ -2806,27 +2807,33 @@ static bool failover_replug_primary(VirtIONet *n, Error **errp) qemu_find_opts("device"), n->primary_device_dict, errp); if (!n->primary_device_opts) { - error_setg(errp, "virtio_net: couldn't find primary device opts"); - goto out; + return false; } } n->primary_bus = n->primary_dev->parent_bus; if (!n->primary_bus) { error_setg(errp, "virtio_net: couldn't find primary bus"); - goto out; + return false; } qdev_set_parent_bus(n->primary_dev, n->primary_bus); n->primary_should_be_hidden = false; qemu_opt_set_bool(n->primary_device_opts, - "partially_hotplugged", true, errp); + "partially_hotplugged", true, &err); + if (err) { + goto out; + } hotplug_ctrl = qdev_get_hotplug_handler(n->primary_dev); if (hotplug_ctrl) { - hotplug_handler_pre_plug(hotplug_ctrl, n->primary_dev, errp); + hotplug_handler_pre_plug(hotplug_ctrl, n->primary_dev, &err); + if (err) { + goto out; + } hotplug_handler_plug(hotplug_ctrl, n->primary_dev, errp); } out: - return *errp == NULL; + error_propagate(errp, err); + return !err; } static void virtio_net_handle_migration_primary(VirtIONet *n, From cb09104ea8418d9521d9a9d36ea0527b84ce51ac Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 30 Nov 2019 20:42:22 +0100 Subject: [PATCH 3/3] block/file-posix: Fix laio_init() error handling crash bug raw_aio_attach_aio_context() passes uninitialized Error *local_err by reference to laio_init() via aio_setup_linux_aio(). When laio_init() fails, it passes it on to error_setg_errno(), tripping error_setv()'s assertion unless @local_err is null by dumb luck. Fix by initializing @local_err properly. Fixes: ed6e2161715c527330f936d44af4c547f25f687e Cc: Nishanth Aravamudan Cc: Stefan Hajnoczi Cc: Kevin Wolf Signed-off-by: Markus Armbruster Message-Id: <20191130194240.10517-4-armbru@redhat.com> Reviewed-by: Stefan Hajnoczi Reviewed-by: Kevin Wolf --- block/file-posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/file-posix.c b/block/file-posix.c index 1f0f61a02b..1b805bd938 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -1973,7 +1973,7 @@ static void raw_aio_attach_aio_context(BlockDriverState *bs, #ifdef CONFIG_LINUX_AIO BDRVRawState *s = bs->opaque; if (s->use_linux_aio) { - Error *local_err; + Error *local_err = NULL; if (!aio_setup_linux_aio(new_context, &local_err)) { error_reportf_err(local_err, "Unable to use native AIO, " "falling back to thread pool: ");