drivers/dma-buf/dma-buf.c | 20 ++++ drivers/dma-buf/dma-heap.c | 80 ++++++------- drivers/gpu/drm/drm_prime.c | 2 +- drivers/misc/fastrpc.c | 16 +-- include/linux/dma-buf.h | 1 + .../selftests/dmabuf-heaps/dmabuf-heap.c | 113 +++++++++++++++++- 6 files changed, 180 insertions(+), 52 deletions(-)
Several drivers call dma_buf_fd() — which internally calls fd_install() — before copy_to_user() returns the fd number to userspace. If copy_to_user() fails, the fd is already published in the caller's fd table but the ioctl returns an error, so userspace never learns the fd number. Worse, the window between fd_install() and copy_to_user() allows other threads to observe and manipulate the fd (dup, close, SCM_RIGHTS), making any "close it on the failure path" fix unsafe. The fix is to split the allocation into three steps: reserve an fd with get_unused_fd_flags() (not yet visible to other threads), do copy_to_user(), and only then publish the fd with fd_install() via the new dma_buf_fd_install() helper. On copy_to_user() failure, put_unused_fd() + dma_buf_put() cleanly unwind with no user-visible side effects. Patch 1 introduces dma_buf_fd_install() in dma-buf.c (wrapping fd_install() together with the DMA_BUF_TRACE call to preserve export tracing) and applies the fix to dma-heap. Patch 2 applies the same fix to fastrpc, which even had a comment acknowledging the problem could not be fixed before. Patch 3 replaces the bare fd_install() in drm_gem_prime_handle_to_fd() with dma_buf_fd_install() to restore tracepoint coverage for DRM PRIME exports (suggested by Christian König). Patch 4 adds a selftest to tools/testing/selftests/dmabuf-heaps/ that reproduces the fd-leak scenario (mprotect flip before the ioctl) and verifies the fd count is unchanged after a failed ioctl (suggested by Sumit Semwal). v1: https://lore.kernel.org/dri-devel/20260703080922.1838362-1-shoubaineng@gmail.com/ v2: https://lore.kernel.org/dri-devel/20260710105740.3080070-1-shoubaineng@gmail.com/ v3: https://lore.kernel.org/dri-devel/20260714114654.3885457-1-shoubaineng@gmail.com/ v5: https://lore.kernel.org/dri-devel/20260730062645.233148-1-shoubaineng@gmail.com/ v6: https://lore.kernel.org/dri-devel/20260807101140.1357218-1-shoubaineng@gmail.com/ Changes in v7: - Add Reviewed-by: T.J. Mercier to patch 4 (selftest). - Add Acked-by: Sumit Semwal to the whole series. Changes in v6: - Rework the selftest (patch 4) per review: extract a count_open_fds() helper, fix the copy_from_user() comment, fail (not skip) when the ioctl does not return -1, drop the bogus mprotect-race mention, and reword the result message. Changes in v5: - Add selftest (patch 4) reproducing the fd-leak scenario (Sumit Semwal) Changes in v4: - Add patch 3: drm/prime: use dma_buf_fd_install() (Christian König) - Add Acked-by: Christian König to patches 1 and 2 Changes in v3: - Split into two patches (dma-heap + fastrpc separately) - Add dma_buf_fd_install() to preserve trace_dma_buf_fd tracepoint - Add fastrpc fix using the new helper (T.J. Mercier) Baineng Shou (4): dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds misc: fastrpc: don't publish fd before copy_to_user() succeeds drm/prime: use dma_buf_fd_install() to preserve export tracing selftests: dmabuf-heaps: add fd-leak-on-EFAULT regression test drivers/dma-buf/dma-buf.c | 20 ++++ drivers/dma-buf/dma-heap.c | 80 ++++++------- drivers/gpu/drm/drm_prime.c | 2 +- drivers/misc/fastrpc.c | 16 +-- include/linux/dma-buf.h | 1 + .../selftests/dmabuf-heaps/dmabuf-heap.c | 113 +++++++++++++++++- 6 files changed, 180 insertions(+), 52 deletions(-) -- 2.34.1
I've gone ahead, added one more rb and pushed the result to drm-misc-fixes. Thanks for the help, Christian. On 8/17/26 07:04, Baineng Shou wrote: > Several drivers call dma_buf_fd() — which internally calls fd_install() > — before copy_to_user() returns the fd number to userspace. If > copy_to_user() fails, the fd is already published in the caller's fd > table but the ioctl returns an error, so userspace never learns the fd > number. Worse, the window between fd_install() and copy_to_user() > allows other threads to observe and manipulate the fd (dup, close, > SCM_RIGHTS), making any "close it on the failure path" fix unsafe. > > The fix is to split the allocation into three steps: reserve an fd with > get_unused_fd_flags() (not yet visible to other threads), do > copy_to_user(), and only then publish the fd with fd_install() via the > new dma_buf_fd_install() helper. On copy_to_user() failure, > put_unused_fd() + dma_buf_put() cleanly unwind with no user-visible > side effects. > > Patch 1 introduces dma_buf_fd_install() in dma-buf.c (wrapping > fd_install() together with the DMA_BUF_TRACE call to preserve export > tracing) and applies the fix to dma-heap. > > Patch 2 applies the same fix to fastrpc, which even had a comment > acknowledging the problem could not be fixed before. > > Patch 3 replaces the bare fd_install() in drm_gem_prime_handle_to_fd() > with dma_buf_fd_install() to restore tracepoint coverage for DRM PRIME > exports (suggested by Christian König). > > Patch 4 adds a selftest to tools/testing/selftests/dmabuf-heaps/ that > reproduces the fd-leak scenario (mprotect flip before the ioctl) and > verifies the fd count is unchanged after a failed ioctl (suggested by > Sumit Semwal). > > v1: https://lore.kernel.org/dri-devel/20260703080922.1838362-1-shoubaineng@gmail.com/ > v2: https://lore.kernel.org/dri-devel/20260710105740.3080070-1-shoubaineng@gmail.com/ > v3: https://lore.kernel.org/dri-devel/20260714114654.3885457-1-shoubaineng@gmail.com/ > v5: https://lore.kernel.org/dri-devel/20260730062645.233148-1-shoubaineng@gmail.com/ > v6: https://lore.kernel.org/dri-devel/20260807101140.1357218-1-shoubaineng@gmail.com/ > > Changes in v7: > - Add Reviewed-by: T.J. Mercier to patch 4 (selftest). > - Add Acked-by: Sumit Semwal to the whole series. > > Changes in v6: > - Rework the selftest (patch 4) per review: extract a count_open_fds() > helper, fix the copy_from_user() comment, fail (not skip) when the > ioctl does not return -1, drop the bogus mprotect-race mention, and > reword the result message. > > Changes in v5: > - Add selftest (patch 4) reproducing the fd-leak scenario (Sumit Semwal) > > Changes in v4: > - Add patch 3: drm/prime: use dma_buf_fd_install() (Christian König) > - Add Acked-by: Christian König to patches 1 and 2 > > Changes in v3: > - Split into two patches (dma-heap + fastrpc separately) > - Add dma_buf_fd_install() to preserve trace_dma_buf_fd tracepoint > - Add fastrpc fix using the new helper (T.J. Mercier) > > Baineng Shou (4): > dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds > misc: fastrpc: don't publish fd before copy_to_user() succeeds > drm/prime: use dma_buf_fd_install() to preserve export tracing > selftests: dmabuf-heaps: add fd-leak-on-EFAULT regression test > > drivers/dma-buf/dma-buf.c | 20 ++++ > drivers/dma-buf/dma-heap.c | 80 ++++++------- > drivers/gpu/drm/drm_prime.c | 2 +- > drivers/misc/fastrpc.c | 16 +-- > include/linux/dma-buf.h | 1 + > .../selftests/dmabuf-heaps/dmabuf-heap.c | 113 +++++++++++++++++- > 6 files changed, 180 insertions(+), 52 deletions(-) >
© 2016 - 2026 Red Hat, Inc.