{"id":29148,"date":"2026-09-25T20:31:59","date_gmt":"2026-09-25T12:31:59","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97992"},"modified":"2026-09-25T20:31:59","modified_gmt":"2026-09-25T12:31:59","slug":"cve-2026-97992","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97992","title":{"rendered":"CVE-2026-97992 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nvhost-vdpa: protect c"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>vhost-vdpa: protect config_ctx from being freed under the config callback<\/p>\n<p>vhost_vdpa_config_cb() loads v-&gt;config_ctx and signals it without taking<br \/>\na reference and without holding any lock:<\/p>\n<p>\tstruct eventfd_ctx *config_ctx = v-&gt;config_ctx;<\/p>\n<p>\tif (config_ctx)<br \/>\n\t\teventfd_signal(config_ctx);<\/p>\n<p>VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally<br \/>\nthe last reference to the old context:<\/p>\n<p>\tswap(ctx, v-&gt;config_ctx);<\/p>\n<p>\tif (ctx)<br \/>\n\t\teventfd_ctx_put(ctx);<\/p>\n<p>eventfd_ctx_put() drops the last kref and frees the context immediately,<br \/>\nwith no RCU grace period, so a callback that has already loaded the<br \/>\npointer goes on to dereference freed memory.  The two sides share no<br \/>\nlock: the ioctl runs under vhost_dev.mutex, while the parent invokes the<br \/>\ncallback from its own interrupt or workqueue context.<\/p>\n<p>This is not the reopen refcount underflow fixed by commit f6bbf0010ba0<br \/>\n(&#8220;vhost-vdpa: fix use-after-free of v-&gt;config_ctx&#8221;), which was about<br \/>\nvhost_vdpa_config_put() leaving a stale pointer behind.  Here the pointer<br \/>\nis maintained correctly and it is the read side that is unprotected.<\/p>\n<p>With VDUSE as the parent this is reachable from userspace with access to<br \/>\n\/dev\/vduse (root by default).  VDUSE_DEV_INJECT_CONFIG_IRQ queues<br \/>\ndev-&gt;inject, and vduse_dev_irq_inject() runs the callback under VDUSE&#8217;s<br \/>\nown dev-&gt;irq_lock, which vhost does not hold.  vduse_dev_reset() does<br \/>\nflush_work(&amp;dev-&gt;inject), but VHOST_VDPA_SET_CONFIG_CALL never goes<br \/>\nthrough reset, so an inject already in flight is not waited for.  A<br \/>\nprocess that injects config interrupts on the VDUSE fd while another<br \/>\nthread swaps the call fd on the vhost-vdpa fd hits it in seconds:<\/p>\n<p>  BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath<br \/>\n  Read of size 4 at addr ffff888107d21808 by task kworker\/u17:1\/2993<br \/>\n  Workqueue: vduse-irq vduse_dev_irq_inject<br \/>\n  Call Trace:<br \/>\n   native_queued_spin_lock_slowpath+0x97\/0x5b0<br \/>\n   _raw_spin_lock_irqsave+0xd4\/0xe0<br \/>\n   eventfd_signal_mask+0x69\/0x120<br \/>\n   vhost_vdpa_config_cb+0x34\/0x50<br \/>\n   vduse_dev_irq_inject+0x46\/0x60<br \/>\n   process_one_work+0x468\/0x950<\/p>\n<p>  Allocated by task 2992:<br \/>\n   do_eventfd+0x50\/0x200<br \/>\n   __x64_sys_eventfd2+0x2e\/0x40<\/p>\n<p>  Freed by task 2992:<br \/>\n   eventfd_ctx_put+0xb9\/0xc0<br \/>\n   vhost_vdpa_unlocked_ioctl+0x116c\/0x2190<\/p>\n<p>Add a spinlock covering every access to config_ctx, so the callback<br \/>\neither signals a context that is still alive or observes NULL, and the<br \/>\nput happens only once no callback can reach the old value.<\/p>\n<p>Clearing the parent&#8217;s callback before the put would not be enough: of the<br \/>\nin-tree set_config_cb() implementations only VDUSE takes a lock, the rest<br \/>\nstore the pointer unlocked, so that would not order against an in-flight<br \/>\ninvocation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>vhost-vdpa: protect config_ctx from being freed under the config callback<\/p>\n<p>vhost_vdpa_config_cb() loads v-&gt;config_ctx and signals i<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-29148","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/29148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=29148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=29148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=29148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}