CVE-2024-37353 in Linux
Zusammenfassung
von VulDB • 30.06.2026
Based on the stack trace and your description, the issue is in `vp_find_vqs_msix` (part of the virtio-pci driver). When `request_irq()` fails for a specific vector/virtual queue (vq), the code currently does not clean up the previously allocated vqs before returning an error. This leads to a crash later when `free_irq` is called on invalid or mismatched state, or during cleanup in `vp_del_vqs`.
The fix should ensure that if `request_irq()` fails for any vector associated with a vq, we properly clean up the resources allocated so far (specifically by calling `del_vring` and freeing interrupts) before returning an error. However, since you specifically asked to "call deleting the current vq when request_irq() fails", here is the targeted fix within `vp_find_vqs_msix`.
### Root Cause In `drivers/virtio/virtio_pci_modern.c`, function `vp_find_vqs_msix`: - It allocates multiple vectors for a single virtqueue (vq). - If `request_irq()` fails for one of these vectors, the previously allocated vring and interrupts are not cleaned up. - Later, when the driver probes fail or during cleanup, it tries to free IRQs that were never properly registered or in an inconsistent state, causing a kernel panic/oops as seen in the trace (`free_irq` called with bad arguments).
### Fix Modify `vp_find_vqs_msix` to clean up the vq (specifically by calling `del_vring` and freeing any successfully allocated IRQs for that vq) if `request_irq()` fails.
Here is the patch:
```diff --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -105,6 +105,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, int err; for (i = 0; i < nvqs; i++) {
+ struct virtnet_info *vi = NULL; /* Placeholder if needed for context */ err = vp_del_vq(vdev->priv); /* This is wrong in original flow? No, let's look at actual code. */ @@ -120,6 +120,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, /* Allocate vectors for this vq */ for (j = 0; j < num_vecs; j++) {
err = request_irq(vi->msix_entries[vec_idx + j].vector, vp_interrupt_msix, 0, name[i], vi);
+ if (err) {
+ /* Clean up the vq: free previously allocated IRQs and del_vring */ + while (--j >= 0) + free_irq(vi->msix_entries[vec_idx + j].vector, vi);
+ del_vring(&vi->vqs[i]); /* Assuming struct virtnet_info has vqs array or similar access */
+ return err; + } } } ```
Wait, the above is pseudo-code. Let's look at the actual structure of `vp_find_vqs_msix` in modern kernels (e.g., Linux 5.x/6.x). The function iterates over vqs and vectors. If `request_irq` fails, we must unwind.
Actually, a more precise fix based on common patterns in this driver:
```diff --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -130,6 +130,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, for (j = 0; j < num_vecs; j++) {
err = request_irq(vi->msix_entries[vec_idx + j].vector,
vp_interrupt_msix, 0, name[i], vi);
+ if (err) {
+ while (--j >= 0) + free_irq(vi->msix_entries[vec_idx + j].vector, vi);
+ del_vring(&vi->vqs[i]); /* Or equivalent cleanup for this vq */
+ return err; + } } ```
However, since I don't have the exact line numbers and structure of your specific kernel version, here is a general conceptual fix that you can apply to `vp_find_vqs_msix`:
**In function `vp_find_vqs_ms
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.