diff options
Diffstat (limited to 'gitlab/issues_toml/target_missing/host_missing/accel_missing/1975.toml')
| -rw-r--r-- | gitlab/issues_toml/target_missing/host_missing/accel_missing/1975.toml | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gitlab/issues_toml/target_missing/host_missing/accel_missing/1975.toml b/gitlab/issues_toml/target_missing/host_missing/accel_missing/1975.toml new file mode 100644 index 000000000..54a2426f7 --- /dev/null +++ b/gitlab/issues_toml/target_missing/host_missing/accel_missing/1975.toml @@ -0,0 +1,47 @@ +id = 1975 +title = "SEGV on exit: net_cleanup() frees devices it doesn't own." +state = "closed" +created_at = "2023-11-09T12:58:40.844Z" +closed_at = "2023-11-27T14:19:45.408Z" +labels = ["kind::Bug", "workflow::Patch available"] +url = "https://gitlab.com/qemu-project/qemu/-/issues/1975" +host-os = "Linux" +host-arch = "x86" +qemu-version = "ad6ef0a42e3 (HEAD as of 2023-11-09)" +guest-os = "N/A" +guest-arch = "N/A" +description = """On exiting QEMU, the `net_cleanup()` function iterates over all existing `net_clients`, both netdevs and nics, and deletes them all. Freeing the netdevs is fine, and they are correctly detached from their peer nic as appropriate. But the nics belong to an actual device and this can cause a use-after-free or double-free. + +Mostly this doesn't happen because emulated devices *don't* bother to clean up after themselves on exit; none of their state is going to outlast the QEMU process so there's no point. But XenBus devices interact with the external XenStore and do need to perform a cleanup. The `xen_netdev_unrealize()` function calls `qemu_del_nic()` on the nic which `net_cleanup()` already stole from it, and crashes... + +``` +QEMU: Terminated + +Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. +qemu_del_nic (nic=0x55555846ab00) at ../net/net.c:451 +451\t int i, queues = MAX(nic->conf->peers.queues, 1); +(gdb) bt +#0 qemu_del_nic (nic=0x55555846ab00) at ../net/net.c:451 +#1 0x0000555555a89ce3 in xen_device_unrealize (dev=<optimized out>) at ../hw/xen/xen-bus.c:973 +#2 0x0000555555e5c847 in notifier_list_notify (list=<optimized out>, data=0x0) at ../util/notify.c:39 +#3 0x00007ffff5fe51e6 in __run_exit_handlers (status=0, listp=<optimized out>, run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) at exit.c:111 +#4 0x00007ffff5fe532e in __GI_exit (status=<optimized out>) at exit.c:141 +#5 0x00007ffff5fccb91 in __libc_start_call_main (main=main@entry=0x5555558837a0 <main>, argc=argc@entry=23, argv=argv@entry=0x7fffffffd7a8) at ../sysdeps/nptl/libc_start_call_main.h:74 +#6 0x00007ffff5fccc4b in __libc_start_main_impl + (main=0x5555558837a0 <main>, argc=23, argv=0x7fffffffd7a8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd798) at ../csu/libc-start.c:360 +#7 0x0000555555885345 in _start () +```""" +reproduce = """1. Launch a Xen guest as described at https://qemu-project.gitlab.io/qemu/system/i386/xen.html (which will get a Xen NIC by default). +2. Terminate QEMU. + +It doesn't need to boot, doesn't need to do anything. Just launch a completely non-functional guest and then hit `Ctrl-a x` on the default monitor: +``` +$ ./qemu-system-x86_64 -accel kvm,xen-version=0x40010,kernel-irqchip=split -display none +QEMU: Terminated +Segmentation fault + +``` + +For `net_cleanup()` to clean up the *netdevs* makes sense, because those might have state which persists in the system after QEMU exits, and need to be cleaned up. But deleting the nics doesn't seem to be necessary. +Fix at https://lore.kernel.org/qemu-devel/61ea91785772a8138ad12b305cbd5aac4aa1e86a.camel@infradead.org""" +additional = "n/a" |