In the Linux kernel, the following vulnerability has been resolved: xen/netfront: destroy queues before realnumtxqueues is zeroed xennetdestroyqueues() relies on info->netdev->realnumtxqueues to delete queues. Since d7dac083414eb5bb99a6d2ed53dc2c1b405224e5 ("net-sysfs: update the queue counts in the unregistration path"), unregisternetdev() indirectly sets realnumtxqueues to 0. Those two facts together means, that xennetdestroyqueues() called from xennetremove() cannot do its job, because it's called after unregisternetdev(). This results in kfree-ing queues that are still linked in napi, which ultimately crashes: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: errorcode(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 52 Comm: xenwatch Tainted: G W 5.16.10-1.32.fc32.qubes.x8664+ #226 RIP: 0010:freenetdev+0xa3/0x1a0 Code: ff 48 89 df e8 2e e9 00 00 48 8b 43 50 48 8b 08 48 8d b8 a0 fe ff ff 48 8d a9 a0 fe ff ff 49 39 c4 75 26 eb 47 e8 ed c1 66 ff <48> 8b 85 60 01 00 00 48 8d 95 60 01 00 00 48 89 ef 48 2d 60 01 00 RSP: 0000:ffffc90000bcfd00 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffff88800edad000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: ffffc90000bcfc30 RDI: 00000000ffffffff RBP: fffffffffffffea0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000001 R12: ffff88800edad050 R13: ffff8880065f8f88 R14: 0000000000000000 R15: ffff8880066c6680 FS: 0000000000000000(0000) GS:ffff8880f3300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000000e998c006 CR4: 00000000003706e0 Call Trace: <TASK> xennetremove+0x13d/0x300 [xennetfront] xenbusdevremove+0x6d/0xf0 _devicereleasedriver+0x17a/0x240 devicereleasedriver+0x24/0x30 busremovedevice+0xd8/0x140 devicedel+0x18b/0x410 ? _rawspinunlock+0x16/0x30 ? klistiterexit+0x14/0x20 ? xenbusdevrequestandreply+0x80/0x80 deviceunregister+0x13/0x60 xenbusdevchanged+0x18e/0x1f0 xenwatchthread+0xc0/0x1a0 ? dowaitintrirq+0xa0/0xa0 kthread+0x16b/0x190 ? setkthreadstruct+0x40/0x40 retfromfork+0x22/0x30 </TASK> Fix this by calling xennetdestroyqueues() from xennetuninit(), when realnumtxqueues is still available. This ensures that queues are destroyed when realnumtxqueues is set to 0, regardless of how unregisternetdev() was called. Originally reported at https://github.com/QubesOS/qubes-issues/issues/7257