{"id":29153,"date":"2026-09-25T20:32:00","date_gmt":"2026-09-25T12:32:00","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97997"},"modified":"2026-09-25T20:32:00","modified_gmt":"2026-09-25T12:32:00","slug":"cve-2026-97997","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-97997","title":{"rendered":"CVE-2026-97997 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\nvirtio_ring: fix stal"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>virtio_ring: fix stale descriptor flags after a failed packed add<\/p>\n<p>In a packed ring the AVAIL and USED bits sit in the descriptor itself,<br \/>\nso writing them makes that descriptor available. Those bit combinations<br \/>\nflip meaning on every round of the ring, tracked by a wrap counter, so<br \/>\ninvalidating or validating a descriptor means inverting both bits.<\/p>\n<p>Commit 1ce9e6055fa0 (&#8220;virtio_ring: introduce packed ring support&#8221;) has<br \/>\nvirtqueue_add_packed() make every descriptor of a chain available as it<br \/>\nmaps the chain, and write the head last. The device consumes the ring in<br \/>\norder and stops at a head that is not available yet, so it never reaches<br \/>\nthe rest.<\/p>\n<p>When vring_map_one_sg() fails partway, unmap_release unmaps the segments<br \/>\nand restores avail_used_flags, but the descriptors it wrote to in the<br \/>\nring stay marked with AVAIL and USED bits. The head is now the only<br \/>\nentry that keeps the device from consuming these stale entries.<\/p>\n<p>For example, the ring would look like this now.<\/p>\n<p>  Z &#8211; pre-previous command<br \/>\n  A &#8211; previous command<br \/>\n  B &#8211; aborted command<br \/>\n  C &#8211; current command<\/p>\n<p>  [A1 DONE] [A2 DONE]  [B2] [B3] [Z1 DONE]<\/p>\n<p>When the driver now attempts to issue the C command, the next add starts<br \/>\nat the same head as B. If C spans less descriptors than B, there is no<br \/>\nend marker because AVAIL and USED bits were still in place. And that<br \/>\nmeans the device will start interpreting these stale entries (B2\/B3) as<br \/>\nanother command entry, which then blocks the queue.<\/p>\n<p>This effect typically happens in swiotlb configurations under memory<br \/>\npressure, because vring_map_one_sg() can then fail with larger I\/O<br \/>\nrequests which then leads to command abortions.<\/p>\n<p>There are broadly 2 ways to avoid leaving those flags behind:<\/p>\n<p>  1) Defer those flags too until the chain is complete.<br \/>\n  2) Rewrite those flags for the previous wrap counter.<\/p>\n<p>Implement the second option in both packed add paths. The first option<br \/>\ntraverses the chain a second time on every successful add. The second<br \/>\noption invalidates all added descriptors when any add fails.<\/p>\n<p>With this patch applied, a packed virtqueue keeps completing requests<br \/>\nafter a failed add.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>virtio_ring: fix stale descriptor flags after a failed packed add<\/p>\n<p>In a packed ring the AVAIL and USED bits sit in the descriptor i<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-29153","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/29153","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=29153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=29153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=29153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}