{
    "dataType": "CVE_RECORD",
    "dataVersion": "5.2",
    "cveMetadata": {
        "cveId": "CVE-2026-74568",
        "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "state": "PUBLISHED",
        "assignerShortName": "Linux",
        "dateReserved": "2026-08-15T05:44:03.917Z",
        "datePublished": "2026-08-15T12:28:08.859Z",
        "dateUpdated": "2026-08-17T05:48:47.432Z"
    },
    "containers": {
        "cna": {
            "providerMetadata": {
                "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
                "shortName": "Linux",
                "dateUpdated": "2026-08-17T05:48:47.432Z"
            },
            "descriptions": [
                {
                    "lang": "en",
                    "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nKVM: arm64: vgic: Fix race between LPI release and re-registration\n\nFix a potential race between decrementing an LPI's reference count and\nevicting that structure from the LPI xarray.\n\nLPI structures are maintained in the VGIC LPI xarray (dist->lpi_xa).\nWhen the reference count of an LPI structure drops to zero,\nvgic_release_lpi_locked() removes the structure from the xarray and\nfrees it under the xarray lock.\n\nHowever, the release of an LPI can race with a concurrent LPI\nre-registration with the same INTID via vgic_add_lpi() on another CPU,\nsince the reference count drop and the xarray eviction are not performed\nin a single atomic step. This can happen e.g. if the guest issues a\nDISCARD while the LPI is still referenced from a vCPU's active-pending\nlist (ap_list), and the same INTID is re-mapped via MAPTI.\n\nParticularly, vgic_release_lpi_locked() is called from two distinct\npaths: direct release via vgic_put_irq(), and deferred release via\nvgic_release_deleted_lpis(). During direct release, the issue can result\nin deleting a newly registered LPI from the xarray:\n\n  CPU0 (Releasing LPI)                    CPU1 (Adding new LPI)\n  ====================                    =====================\n  vgic_put_irq()\n      __vgic_put_irq()\n          refcount_dec_and_test()\n                                          vgic_add_lpi()\n                                              xa_lock_irqsave()\n                                              old_irq = xa_load(.., intid)\n                                              vgic_try_get_irq_ref(old_irq) == false\n                        new IRQ inserted -->  __xa_store(.., intid, ..)\n                                              xa_unlock_irqrestore()\n  xa_lock_irqsave();\n  vgic_release_lpi_locked()\n      __xa_erase(.., irq->intid)   <-- BUG: new IRQ is erased\n      kfree_rcu(old_irq)\n\nDuring the deferred release path, the old IRQ can be leaked:\n\n  CPU0 (Releasing LPI)                    CPU1 (Adding new LPI)\n  ====================                    =====================\n  vgic_put_irq_norelease()\n      __vgic_put_irq()\n          refcount_dec_and_test()\n      irq->pending_release = true\n                                          vgic_add_lpi()\n                                              xa_lock_irqsave()\n                                              old_irq = xa_load(.., intid)\n                                              vgic_try_get_irq_ref(oldirq) == false\n                 BUG: old IRQ overwritten --> __xa_store(.., intid, ..)\n                                              xa_unlock_irqrestore()\n\n  vgic_release_deleted_lpis()\n      xa_lock_irqsave()\n      xa_for_each() { .. } <-- old IRQ with pending_release = true\n                               is gone, so it cannot be released\n\nTo fix the direct release path, move the reference count drop inside\nthe xarray lock, making sure that vgic_add_lpi() never encounters the\nto-be-released LPI.\n\nIn the deferred release path, the refcount drop must happen under a raw\nspinlock, so the xarray lock cannot be grabbed, and the same solution\ndoes not work. Instead, update vgic_add_lpi(), so that if it evicts\nan LPI from the xarray, it takes on the responsibility of freeing it.\nConsequently, an LPI may now be freed concurrently after a deferred\nrelease drops the refcount, so accessing the pending_release field is no\nlonger safe from use-after-free. Delete all uses of the flag, and update\nvgic_release_deleted_lpis() to identify orphaned LPIs purely based on\ntheir refcount."
                }
            ],
            "metrics": [
                {
                    "cvssV3_1": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
                        "baseScore": 9.3,
                        "baseSeverity": "CRITICAL"
                    },
                    "scenarios": [
                        {
                            "lang": "en",
                            "value": "AV:L - The bug is reached when a malicious KVM guest writes emulated GICv3 ITS MMIO (GITS_CWRITER), processing DISCARD/MAPTI commands that call vgic_add_lpi() and vgic_put_irq(); this requires guest code execution on the host, not remote network input.\nAC:L - The race is guest-driven and repeatable: a malicious guest can keep an LPI referenced on a vCPU ap_list, issue DISCARD, and concurrently re-map the same INTID via MAPTI across vCPUs, controlling both sides of the refcount/xarray race.\nPR:N - Exploitation requires only code inside a KVM guest on an arm64 host with VGICv3 ITS/LPI (common on cloud ARM servers); no host root, CAP_SYS_ADMIN, or other elevated host privileges are needed beyond normal VM tenancy.\nUI:N - No victim interaction is required; the attacker fully controls guest ITS command submission, interrupt injection, and multi-vCPU timing from within the VM.\nS:C - Corrupting host-kernel VGIC LPI objects (lpi_xa entries, vgic_irq structures) from guest MMIO crosses the KVM virtual-machine security boundary and can enable guest-to-host escape.\nC:H - The race can erase a newly registered LPI while freeing the old one, leaving stale host pointers (ite->irq, ap_list) to freed vgic_irq objects; this use-after-free enables arbitrary host kernel memory disclosure via heap reuse.\nI:H - Host heap corruption of vgic_irq structures and xarray state from the race provides use-after-free write primitives that can be leveraged for arbitrary host kernel modification and VM escape code execution.\nA:H - The bug can cause host kernel crashes (oops/panic) from freeing live LPIs, orphaned IRQ state, and use-after-free during concurrent VGIC interrupt handling on multiple vCPUs."
                        }
                    ]
                }
            ],
            "affected": [
                {
                    "product": "Linux",
                    "vendor": "Linux",
                    "defaultStatus": "unaffected",
                    "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
                    "programFiles": [
                        "arch/arm64/kvm/vgic/vgic-its.c",
                        "arch/arm64/kvm/vgic/vgic.c",
                        "include/kvm/arm_vgic.h"
                    ],
                    "versions": [
                        {
                            "version": "3a08a6ca7c373198c84e2a8c025c395ee966ff8a",
                            "lessThan": "292e80a159aa88635bf668a7212cfdf526b8bd52",
                            "status": "affected",
                            "versionType": "git"
                        },
                        {
                            "version": "3a08a6ca7c373198c84e2a8c025c395ee966ff8a",
                            "lessThan": "cbfe2b24a1ea9de35032dbdd100fdc700f5be92d",
                            "status": "affected",
                            "versionType": "git"
                        }
                    ]
                },
                {
                    "product": "Linux",
                    "vendor": "Linux",
                    "defaultStatus": "affected",
                    "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
                    "programFiles": [
                        "arch/arm64/kvm/vgic/vgic-its.c",
                        "arch/arm64/kvm/vgic/vgic.c",
                        "include/kvm/arm_vgic.h"
                    ],
                    "versions": [
                        {
                            "version": "6.17",
                            "status": "affected"
                        },
                        {
                            "version": "0",
                            "lessThan": "6.17",
                            "status": "unaffected",
                            "versionType": "semver"
                        },
                        {
                            "version": "7.1.8",
                            "lessThanOrEqual": "7.1.*",
                            "status": "unaffected",
                            "versionType": "semver"
                        },
                        {
                            "version": "7.2",
                            "lessThanOrEqual": "*",
                            "status": "unaffected",
                            "versionType": "original_commit_for_fix"
                        }
                    ]
                }
            ],
            "cpeApplicability": [
                {
                    "nodes": [
                        {
                            "operator": "OR",
                            "negate": false,
                            "cpeMatch": [
                                {
                                    "vulnerable": true,
                                    "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                                    "versionStartIncluding": "6.17",
                                    "versionEndExcluding": "7.1.8"
                                },
                                {
                                    "vulnerable": true,
                                    "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                                    "versionStartIncluding": "6.17",
                                    "versionEndExcluding": "7.2"
                                }
                            ]
                        }
                    ]
                }
            ],
            "references": [
                {
                    "url": "https://git.kernel.org/stable/c/292e80a159aa88635bf668a7212cfdf526b8bd52"
                },
                {
                    "url": "https://git.kernel.org/stable/c/cbfe2b24a1ea9de35032dbdd100fdc700f5be92d"
                }
            ],
            "title": "KVM: arm64: vgic: Fix race between LPI release and re-registration",
            "x_generator": {
                "engine": "bippy-1.2.0"
            }
        }
    }
}