Description
In the Linux kernel, the following vulnerability has been resolved:

vhost-vdpa: protect config_ctx from being freed under the config callback

vhost_vdpa_config_cb() loads v->config_ctx and signals it without taking
a reference and without holding any lock:

struct eventfd_ctx *config_ctx = v->config_ctx;

if (config_ctx)
eventfd_signal(config_ctx);

VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally
the last reference to the old context:

swap(ctx, v->config_ctx);

if (ctx)
eventfd_ctx_put(ctx);

eventfd_ctx_put() drops the last kref and frees the context immediately,
with no RCU grace period, so a callback that has already loaded the
pointer goes on to dereference freed memory. The two sides share no
lock: the ioctl runs under vhost_dev.mutex, while the parent invokes the
callback from its own interrupt or workqueue context.

This is not the reopen refcount underflow fixed by commit f6bbf0010ba0
("vhost-vdpa: fix use-after-free of v->config_ctx"), which was about
vhost_vdpa_config_put() leaving a stale pointer behind. Here the pointer
is maintained correctly and it is the read side that is unprotected.

With VDUSE as the parent this is reachable from userspace with access to
/dev/vduse (root by default). VDUSE_DEV_INJECT_CONFIG_IRQ queues
dev->inject, and vduse_dev_irq_inject() runs the callback under VDUSE's
own dev->irq_lock, which vhost does not hold. vduse_dev_reset() does
flush_work(&dev->inject), but VHOST_VDPA_SET_CONFIG_CALL never goes
through reset, so an inject already in flight is not waited for. A
process that injects config interrupts on the VDUSE fd while another
thread swaps the call fd on the vhost-vdpa fd hits it in seconds:

BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath
Read of size 4 at addr ffff888107d21808 by task kworker/u17:1/2993
Workqueue: vduse-irq vduse_dev_irq_inject
Call Trace:
native_queued_spin_lock_slowpath+0x97/0x5b0
_raw_spin_lock_irqsave+0xd4/0xe0
eventfd_signal_mask+0x69/0x120
vhost_vdpa_config_cb+0x34/0x50
vduse_dev_irq_inject+0x46/0x60
process_one_work+0x468/0x950

Allocated by task 2992:
do_eventfd+0x50/0x200
__x64_sys_eventfd2+0x2e/0x40

Freed by task 2992:
eventfd_ctx_put+0xb9/0xc0
vhost_vdpa_unlocked_ioctl+0x116c/0x2190

Add a spinlock covering every access to config_ctx, so the callback
either signals a context that is still alive or observes NULL, and the
put happens only once no callback can reach the old value.

Clearing the parent's callback before the put would not be enough: of the
in-tree set_config_cb() implementations only VDUSE takes a lock, the rest
store the pointer unlocked, so that would not order against an in-flight
invocation.
Published: 2026-09-25
Score: n/a
EPSS: n/a
KEV: No
Impact: Kernel Use‑After‑Free
Action: Apply Patch
AI Analysis

Impact

In the Linux kernel, the vhost‑vdpa driver permits the configuration callback to read a context pointer without taking a reference or holding a lock. While the callback performs a signal on the context, another thread can swap the pointer and decrement the reference count, freeing the context without a grace period. This race causes the callback to dereference freed memory, leading to a kernel memory corruption, crash, or potentially arbitrary code execution by a local attacker.

Affected Systems

The flaw affects any Linux kernel that contains the unpatched vhost‑vdpa driver. Access to the /dev/vduse device is required, which is normally owned by root. A local process with root or equivalent privileges can inject configuration interrupts on VDUSE while another thread swaps the vhost‑vdpa callback, triggering the use‑after‑free. No non‑root escalation path is documented.

Risk and Exploitability

No public CVSS or EPSS score is supplied, but the presence of a classic use‑after‑free that corrupts kernel memory indicates a high‑severity issue. Exploitation is limited to concurrent privileged access to /dev/vduse and a vhost‑vdpa device, so it is a local privilege escalation risk. The vulnerability is not listed in CISA KEV, yet it warrants immediate attention because it can allow an attacker to execute code in kernel mode.

Generated by OpenCVE AI on September 25, 2026 at 15:29 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Update the Linux kernel to a version that contains the fix for the vhost‑vdpa use‑after‑free.
  • Reboot after the kernel update so that the updated driver is loaded.
  • Restrict access to /dev/vduse (or disable the VDUSE module) by setting a strict ownership or applying SELinux/AppArmor rules, ensuring only trusted users can interact with the device.
  • If an immediate kernel upgrade is not possible, temporarily unload or disable the VDUSE kernel module to prevent concurrent injection of configuration interrupts while the vulnerability is present.

Generated by OpenCVE AI on September 25, 2026 at 15:29 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Fri, 25 Sep 2026 15:45:00 +0000

Type Values Removed Values Added
Weaknesses CWE-416

Fri, 25 Sep 2026 10:30:00 +0000

Type Values Removed Values Added
Description In the Linux kernel, the following vulnerability has been resolved: vhost-vdpa: protect config_ctx from being freed under the config callback vhost_vdpa_config_cb() loads v->config_ctx and signals it without taking a reference and without holding any lock: struct eventfd_ctx *config_ctx = v->config_ctx; if (config_ctx) eventfd_signal(config_ctx); VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally the last reference to the old context: swap(ctx, v->config_ctx); if (ctx) eventfd_ctx_put(ctx); eventfd_ctx_put() drops the last kref and frees the context immediately, with no RCU grace period, so a callback that has already loaded the pointer goes on to dereference freed memory. The two sides share no lock: the ioctl runs under vhost_dev.mutex, while the parent invokes the callback from its own interrupt or workqueue context. This is not the reopen refcount underflow fixed by commit f6bbf0010ba0 ("vhost-vdpa: fix use-after-free of v->config_ctx"), which was about vhost_vdpa_config_put() leaving a stale pointer behind. Here the pointer is maintained correctly and it is the read side that is unprotected. With VDUSE as the parent this is reachable from userspace with access to /dev/vduse (root by default). VDUSE_DEV_INJECT_CONFIG_IRQ queues dev->inject, and vduse_dev_irq_inject() runs the callback under VDUSE's own dev->irq_lock, which vhost does not hold. vduse_dev_reset() does flush_work(&dev->inject), but VHOST_VDPA_SET_CONFIG_CALL never goes through reset, so an inject already in flight is not waited for. A process that injects config interrupts on the VDUSE fd while another thread swaps the call fd on the vhost-vdpa fd hits it in seconds: BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath Read of size 4 at addr ffff888107d21808 by task kworker/u17:1/2993 Workqueue: vduse-irq vduse_dev_irq_inject Call Trace: native_queued_spin_lock_slowpath+0x97/0x5b0 _raw_spin_lock_irqsave+0xd4/0xe0 eventfd_signal_mask+0x69/0x120 vhost_vdpa_config_cb+0x34/0x50 vduse_dev_irq_inject+0x46/0x60 process_one_work+0x468/0x950 Allocated by task 2992: do_eventfd+0x50/0x200 __x64_sys_eventfd2+0x2e/0x40 Freed by task 2992: eventfd_ctx_put+0xb9/0xc0 vhost_vdpa_unlocked_ioctl+0x116c/0x2190 Add a spinlock covering every access to config_ctx, so the callback either signals a context that is still alive or observes NULL, and the put happens only once no callback can reach the old value. Clearing the parent's callback before the put would not be enough: of the in-tree set_config_cb() implementations only VDUSE takes a lock, the rest store the pointer unlocked, so that would not order against an in-flight invocation.
Title vhost-vdpa: protect config_ctx from being freed under the config callback
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-09-25T10:23:24.472Z

Reserved: 2026-09-25T10:18:58.209Z

Link: CVE-2026-97992

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-09-25T11:17:27.343

Modified: 2026-09-25T11:17:27.343

Link: CVE-2026-97992

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-09-25T15:30:06Z

Weaknesses