Skip to content

Commit b068656

Browse files
Li ZetaoPaolo Abeni
authored andcommitted
virtio_net: Fix probe failed when modprobe virtio_net
When doing the following test steps, an error was found: step 1: modprobe virtio_net succeeded # modprobe virtio_net <-- OK step 2: fault injection in register_netdevice() # modprobe -r virtio_net <-- OK # ... FAULT_INJECTION: forcing a failure. name failslab, interval 1, probability 0, space 0, times 0 CPU: 0 PID: 3521 Comm: modprobe Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), Call Trace: <TASK> ... should_failslab+0xa/0x20 ... dev_set_name+0xc0/0x100 netdev_register_kobject+0xc2/0x340 register_netdevice+0xbb9/0x1320 virtnet_probe+0x1d72/0x2658 [virtio_net] ... </TASK> virtio_net: probe of virtio0 failed with error -22 step 3: modprobe virtio_net failed # modprobe virtio_net <-- failed virtio_net: probe of virtio0 failed with error -2 The root cause of the problem is that the queues are not disable on the error handling path when register_netdevice() fails in virtnet_probe(), resulting in an error "-ENOENT" returned in the next modprobe call in setup_vq(). virtio_pci_modern_device uses virtqueues to send or receive message, and "queue_enable" records whether the queues are available. In vp_modern_find_vqs(), all queues will be selected and activated, but once queues are enabled there is no way to go back except reset. Fix it by reset virtio device on error handling path. This makes error handling follow the same order as normal device cleanup in virtnet_remove() which does: unregister, destroy failover, then reset. And that flow is better tested than error handling so we can be reasonably sure it works well. Fixes: 0246555 ("virtio_net: fix use after free on allocation failure") Signed-off-by: Li Zetao <lizetao1@huawei.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Link: https://lore.kernel.org/r/20221122150046.3910638-1-lizetao1@huawei.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 08e8a94 commit b068656

1 file changed

Lines changed: 1 addition & 2 deletions

File tree

drivers/net/virtio_net.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,12 +3949,11 @@ static int virtnet_probe(struct virtio_device *vdev)
39493949
return 0;
39503950

39513951
free_unregister_netdev:
3952-
virtio_reset_device(vdev);
3953-
39543952
unregister_netdev(dev);
39553953
free_failover:
39563954
net_failover_destroy(vi->failover);
39573955
free_vqs:
3956+
virtio_reset_device(vdev);
39583957
cancel_delayed_work_sync(&vi->refill);
39593958
free_receive_page_frags(vi);
39603959
virtnet_del_vqs(vi);

0 commit comments

Comments
 (0)