Hi David,
Thanks for the feedback.
The concern is not just about the EFAULT return — it's about the race
window between fd_install() and copy_to_user(). Once fd_install()
returns, the fd is immediately observable by other threads in the same
process (via /proc/self/fd, SCM_RIGHTS, etc.), even before
copy_to_user() has a chance to fail. The triggering condition is a
deliberate mprotect() flip, not a corrupted heap.
The fix itself is small and follows the standard kernel idiom:
get_unused_fd_flags() reserves the fd without publishing it, so the
window between reservation and install is entirely under kernel control.
Baineng
On Tue, 14 Jul 2026 19:46:53 +0800
Baineng Shou <shoubaineng@gmail.com> wrote:
> DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd into the
> caller's fd table via dma_buf_fd() -> fd_install() before
> dma_heap_ioctl() copies the result back to userspace. If the trailing
> copy_to_user() fails, userspace never learns the fd number, but the
> fd (and the underlying dma-buf reference) are already visible to
> other threads in the same process and are leaked for the lifetime of
> the process.
>
> The obvious "close it on the failure path" fix is unsafe: once
> fd_install() has run, another thread can already dup() the fd, send
> it via SCM_RIGHTS, or close() it and let its number be reused, so a
> subsequent close_fd() from the ioctl path can operate on an unrelated
> file. This was pointed out by Christian König on v1 [1].
...
My 2c:
The other option is just to leave it as a 'problem for user space'.
No reasonable program is going to handle the EFAULT return by doing
anything other than exiting.
Even getting an EFAULT is really an indication that the application
is already in a real mess - most likely with a badly corrupted heap.
Anything else leaves error recovery code in the kernel that is pretty
much never executed and open to a variety of bugs.
While the recovery here is probably ok, there are some sockopt calls
where it is all more complicated.
David