CVE-2026-74568 (GCVE-0-2026-74568)
Vulnerability from cvelistv5
Published
2026-08-15 12:28
Modified
2026-10-16 19:05
Severity ?
VLAI Severity ?
EPSS score ?
Summary
In the Linux kernel, the following vulnerability has been resolved:
KVM: arm64: vgic: Fix race between LPI release and re-registration
Fix a potential race between decrementing an LPI's reference count and
evicting that structure from the LPI xarray.
LPI structures are maintained in the VGIC LPI xarray (dist->lpi_xa).
When the reference count of an LPI structure drops to zero,
vgic_release_lpi_locked() removes the structure from the xarray and
frees it under the xarray lock.
However, the release of an LPI can race with a concurrent LPI
re-registration with the same INTID via vgic_add_lpi() on another CPU,
since the reference count drop and the xarray eviction are not performed
in a single atomic step. This can happen e.g. if the guest issues a
DISCARD while the LPI is still referenced from a vCPU's active-pending
list (ap_list), and the same INTID is re-mapped via MAPTI.
Particularly, vgic_release_lpi_locked() is called from two distinct
paths: direct release via vgic_put_irq(), and deferred release via
vgic_release_deleted_lpis(). During direct release, the issue can result
in deleting a newly registered LPI from the xarray:
CPU0 (Releasing LPI) CPU1 (Adding new LPI)
==================== =====================
vgic_put_irq()
__vgic_put_irq()
refcount_dec_and_test()
vgic_add_lpi()
xa_lock_irqsave()
old_irq = xa_load(.., intid)
vgic_try_get_irq_ref(old_irq) == false
new IRQ inserted --> __xa_store(.., intid, ..)
xa_unlock_irqrestore()
xa_lock_irqsave();
vgic_release_lpi_locked()
__xa_erase(.., irq->intid) <-- BUG: new IRQ is erased
kfree_rcu(old_irq)
During the deferred release path, the old IRQ can be leaked:
CPU0 (Releasing LPI) CPU1 (Adding new LPI)
==================== =====================
vgic_put_irq_norelease()
__vgic_put_irq()
refcount_dec_and_test()
irq->pending_release = true
vgic_add_lpi()
xa_lock_irqsave()
old_irq = xa_load(.., intid)
vgic_try_get_irq_ref(oldirq) == false
BUG: old IRQ overwritten --> __xa_store(.., intid, ..)
xa_unlock_irqrestore()
vgic_release_deleted_lpis()
xa_lock_irqsave()
xa_for_each() { .. } <-- old IRQ with pending_release = true
is gone, so it cannot be released
To fix the direct release path, move the reference count drop inside
the xarray lock, making sure that vgic_add_lpi() never encounters the
to-be-released LPI.
In the deferred release path, the refcount drop must happen under a raw
spinlock, so the xarray lock cannot be grabbed, and the same solution
does not work. Instead, update vgic_add_lpi(), so that if it evicts
an LPI from the xarray, it takes on the responsibility of freeing it.
Consequently, an LPI may now be freed concurrently after a deferred
release drops the refcount, so accessing the pending_release field is no
longer safe from use-after-free. Delete all uses of the flag, and update
vgic_release_deleted_lpis() to identify orphaned LPIs purely based on
their refcount.
References
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-74568",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-16T19:00:27.387340Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-16T19:05:56.525Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"arch/arm64/kvm/vgic/vgic-its.c",
"arch/arm64/kvm/vgic/vgic.c",
"include/kvm/arm_vgic.h"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "f8e5715a37378ea1a140ee1162fa441e149c5142",
"status": "affected",
"version": "3a08a6ca7c373198c84e2a8c025c395ee966ff8a",
"versionType": "git"
},
{
"lessThan": "292e80a159aa88635bf668a7212cfdf526b8bd52",
"status": "affected",
"version": "3a08a6ca7c373198c84e2a8c025c395ee966ff8a",
"versionType": "git"
},
{
"lessThan": "cbfe2b24a1ea9de35032dbdd100fdc700f5be92d",
"status": "affected",
"version": "3a08a6ca7c373198c84e2a8c025c395ee966ff8a",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"arch/arm64/kvm/vgic/vgic-its.c",
"arch/arm64/kvm/vgic/vgic.c",
"include/kvm/arm_vgic.h"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "6.17"
},
{
"lessThan": "6.17",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.18.*",
"status": "unaffected",
"version": "6.18.57",
"versionType": "semver"
},
{
"lessThanOrEqual": "7.1.*",
"status": "unaffected",
"version": "7.1.8",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "7.2",
"versionType": "original_commit_for_fix"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.18.57",
"versionStartIncluding": "6.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "7.1.8",
"versionStartIncluding": "6.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "7.2",
"versionStartIncluding": "6.17",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"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\u0027s reference count and\nevicting that structure from the LPI xarray.\n\nLPI structures are maintained in the VGIC LPI xarray (dist-\u003elpi_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\u0027s 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 --\u003e __xa_store(.., intid, ..)\n xa_unlock_irqrestore()\n xa_lock_irqsave();\n vgic_release_lpi_locked()\n __xa_erase(.., irq-\u003eintid) \u003c-- 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-\u003epending_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 --\u003e __xa_store(.., intid, ..)\n xa_unlock_irqrestore()\n\n vgic_release_deleted_lpis()\n xa_lock_irqsave()\n xa_for_each() { .. } \u003c-- 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": {
"baseScore": 9.3,
"baseSeverity": "CRITICAL",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"version": "3.1"
},
"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-\u003eirq, 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."
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-15T10:09:17.216Z",
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux"
},
"references": [
{
"url": "https://git.kernel.org/stable/c/f8e5715a37378ea1a140ee1162fa441e149c5142"
},
{
"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"
}
}
},
"cveMetadata": {
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"assignerShortName": "Linux",
"cveId": "CVE-2026-74568",
"datePublished": "2026-08-15T12:28:08.859Z",
"dateReserved": "2026-08-15T05:44:03.917Z",
"dateUpdated": "2026-10-16T19:05:56.525Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"vulnrichment": {
"containers": "{\"cna\": {\"title\": \"KVM: arm64: vgic: Fix race between LPI release and re-registration\", \"metrics\": [{\"cvssV3_1\": {\"version\": \"3.1\", \"baseScore\": 9.3, \"baseSeverity\": \"CRITICAL\", \"vectorString\": \"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H\"}, \"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-\u003eirq, 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\": [{\"repo\": \"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\", \"vendor\": \"Linux\", \"product\": \"Linux\", \"versions\": [{\"status\": \"affected\", \"version\": \"3a08a6ca7c373198c84e2a8c025c395ee966ff8a\", \"lessThan\": \"f8e5715a37378ea1a140ee1162fa441e149c5142\", \"versionType\": \"git\"}, {\"status\": \"affected\", \"version\": \"3a08a6ca7c373198c84e2a8c025c395ee966ff8a\", \"lessThan\": \"292e80a159aa88635bf668a7212cfdf526b8bd52\", \"versionType\": \"git\"}, {\"status\": \"affected\", \"version\": \"3a08a6ca7c373198c84e2a8c025c395ee966ff8a\", \"lessThan\": \"cbfe2b24a1ea9de35032dbdd100fdc700f5be92d\", \"versionType\": \"git\"}], \"programFiles\": [\"arch/arm64/kvm/vgic/vgic-its.c\", \"arch/arm64/kvm/vgic/vgic.c\", \"include/kvm/arm_vgic.h\"], \"defaultStatus\": \"unaffected\"}, {\"repo\": \"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git\", \"vendor\": \"Linux\", \"product\": \"Linux\", \"versions\": [{\"status\": \"affected\", \"version\": \"6.17\"}, {\"status\": \"unaffected\", \"version\": \"0\", \"lessThan\": \"6.17\", \"versionType\": \"semver\"}, {\"status\": \"unaffected\", \"version\": \"6.18.57\", \"versionType\": \"semver\", \"lessThanOrEqual\": \"6.18.*\"}, {\"status\": \"unaffected\", \"version\": \"7.1.8\", \"versionType\": \"semver\", \"lessThanOrEqual\": \"7.1.*\"}, {\"status\": \"unaffected\", \"version\": \"7.2\", \"versionType\": \"original_commit_for_fix\", \"lessThanOrEqual\": \"*\"}], \"programFiles\": [\"arch/arm64/kvm/vgic/vgic-its.c\", \"arch/arm64/kvm/vgic/vgic.c\", \"include/kvm/arm_vgic.h\"], \"defaultStatus\": \"affected\"}], \"references\": [{\"url\": \"https://git.kernel.org/stable/c/f8e5715a37378ea1a140ee1162fa441e149c5142\"}, {\"url\": \"https://git.kernel.org/stable/c/292e80a159aa88635bf668a7212cfdf526b8bd52\"}, {\"url\": \"https://git.kernel.org/stable/c/cbfe2b24a1ea9de35032dbdd100fdc700f5be92d\"}], \"x_generator\": {\"engine\": \"bippy-1.2.0\"}, \"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\u0027s reference count and\\nevicting that structure from the LPI xarray.\\n\\nLPI structures are maintained in the VGIC LPI xarray (dist-\u003elpi_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\u0027s 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 --\u003e __xa_store(.., intid, ..)\\n xa_unlock_irqrestore()\\n xa_lock_irqsave();\\n vgic_release_lpi_locked()\\n __xa_erase(.., irq-\u003eintid) \u003c-- 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-\u003epending_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 --\u003e __xa_store(.., intid, ..)\\n xa_unlock_irqrestore()\\n\\n vgic_release_deleted_lpis()\\n xa_lock_irqsave()\\n xa_for_each() { .. } \u003c-- 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.\"}], \"cpeApplicability\": [{\"nodes\": [{\"negate\": false, \"cpeMatch\": [{\"criteria\": \"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\", \"vulnerable\": true, \"versionEndExcluding\": \"6.18.57\", \"versionStartIncluding\": \"6.17\"}, {\"criteria\": \"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\", \"vulnerable\": true, \"versionEndExcluding\": \"7.1.8\", \"versionStartIncluding\": \"6.17\"}, {\"criteria\": \"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*\", \"vulnerable\": true, \"versionEndExcluding\": \"7.2\", \"versionStartIncluding\": \"6.17\"}], \"operator\": \"OR\"}]}], \"providerMetadata\": {\"orgId\": \"416baaa9-dc9f-4396-8d5f-8c081fb06d67\", \"shortName\": \"Linux\", \"dateUpdated\": \"2026-10-15T10:09:17.216Z\"}}, \"adp\": [{\"title\": \"CISA ADP Vulnrichment\", \"metrics\": [{\"other\": {\"type\": \"ssvc\", \"content\": {\"id\": \"CVE-2026-74568\", \"role\": \"CISA Coordinator\", \"options\": [{\"Exploitation\": \"none\"}, {\"Automatable\": \"no\"}, {\"Technical Impact\": \"total\"}], \"version\": \"2.0.3\", \"timestamp\": \"2026-10-16T19:00:27.387340Z\"}}}], \"providerMetadata\": {\"shortName\": \"CISA-ADP\", \"orgId\": \"134c704f-9b21-4f2e-91b3-4a467353bcc0\", \"dateUpdated\": \"2026-10-16T19:00:27.996Z\"}}]}",
"cveMetadata": "{\"cveId\": \"CVE-2026-74568\", \"state\": \"PUBLISHED\", \"dateUpdated\": \"2026-10-15T10:09:17.216Z\", \"dateReserved\": \"2026-08-15T05:44:03.917Z\", \"assignerOrgId\": \"416baaa9-dc9f-4396-8d5f-8c081fb06d67\", \"datePublished\": \"2026-08-15T12:28:08.859Z\", \"assignerShortName\": \"Linux\"}",
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
}
}
Loading…
Loading…
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.
Loading…
Loading…