{"id":24683,"date":"2026-09-16T20:32:38","date_gmt":"2026-09-16T12:32:38","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-89996"},"modified":"2026-09-16T20:32:38","modified_gmt":"2026-09-16T12:32:38","slug":"cve-2026-89996","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-89996","title":{"rendered":"CVE-2026-89996 &#8211; In the Linux kernel, the following vulnerability has been resolved:\n\ndma-buf: dma-heap: do"},"content":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>dma-buf: dma-heap: don&#8217;t publish fd before copy_to_user() succeeds<\/p>\n<p>DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd into the<br \/>\ncaller&#8217;s fd table via dma_buf_fd() -&gt; fd_install() before<br \/>\ndma_heap_ioctl() copies the result back to userspace.  If the trailing<br \/>\ncopy_to_user() fails, userspace never learns the fd number, but the<br \/>\nfd (and the underlying dma-buf reference) are already visible to<br \/>\nother threads in the same process and are leaked for the lifetime of<br \/>\nthe process.<\/p>\n<p>The obvious &#8220;close it on the failure path&#8221; fix is unsafe: once<br \/>\nfd_install() has run, another thread can already dup() the fd, send<br \/>\nit via SCM_RIGHTS, or close() it and let its number be reused, so a<br \/>\nsubsequent close_fd() from the ioctl path can operate on an unrelated<br \/>\nfile.  This was pointed out by Christian K\u00f6nig on v1 [1].<\/p>\n<p>Restructure the allocation path so that fd_install() is the last,<br \/>\nunfailable step of a successful ioctl:<\/p>\n<p>  1. heap-&gt;ops-&gt;allocate()      creates the dma_buf.<br \/>\n  2. get_unused_fd_flags()      reserves an fd number in the caller&#8217;s<br \/>\n                                fd table without publishing it, so<br \/>\n                                no other thread can observe it.<br \/>\n  3. copy_to_user()             delivers the fd number to userspace;<br \/>\n                                on failure the fd is returned with<br \/>\n                                put_unused_fd() and the dma_buf<br \/>\n                                reference is dropped with<br \/>\n                                dma_buf_put(), leaving no user-<br \/>\n                                visible state behind.<br \/>\n  4. dma_buf_fd_install()       publishes the fd and emits the<br \/>\n                                trace_dma_buf_fd tracepoint &#8212; from<br \/>\n                                here on the ioctl cannot fail.<\/p>\n<p>A new dma_buf_fd_install() helper is introduced in dma-buf.c to wrap<br \/>\nfd_install() together with the DMA_BUF_TRACE() call, preserving the<br \/>\nexport tracing that dma_buf_fd() provides.  dma_heap_ioctl_allocate()<br \/>\nis refactored to return the struct dma_buf * directly (returning<br \/>\nERR_PTR on failure) so the caller holds the dmabuf reference across<br \/>\nsteps 3 and 4.<\/p>\n<p>The failure at step 3 is easily reachable from userspace: pass a<br \/>\nstruct dma_heap_allocation_data that lives in a page whose protection<br \/>\nis flipped to PROT_READ between copy_from_user() and copy_to_user()<br \/>\n(e.g. via mprotect()).  Before this change each such ioctl leaks one<br \/>\ndmabuf fd; after it, the fd table is unchanged on failure and only<br \/>\n\/dev\/dma_heap\/ remains open.<\/p>\n<p>No UAPI or heap-driver interface change.<\/p>\n<p>[1] https:\/\/lore.kernel.org\/dri-devel\/175e98de-f414-47d7-81c1-c0fe0a8f7f62@amd.com\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the Linux kernel, the following vulnerability has been resolved:<\/p>\n<p>dma-buf: dma-heap: don&#8217;t publish fd before copy_to_user() succeeds<\/p>\n<p>DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd int<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-24683","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/24683","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=24683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=24683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=24683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}