β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2134

dma_buf_fd silently ignores O_CLOEXEC -- fd leaks across exec()

Field Value
ID DF-2134
Status new
Severity Info
CVSS 3.1 CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
CWE CWE-403 Exposure of File Descriptor to Unintended Control Sphere
File sys/dev/drm/linux_dma-buf.c
Lines 150-157
Area drm/linuxkpi
Confidence certain
Discovered 2026-07-25
Reported pending
Known CVE none
CVE match dfly_specific

Summary

dma_buf_fd() accepts O_CLOEXEC in the flags parameter but the implementation is a stub (#if 0 block). The dma-buf fd is never marked close-on-exec, so it survives execve() even when userspace explicitly requested O_CLOEXEC via DRM_IOCTL_PRIME_HANDLE_TO_FD with DRM_CLOEXEC. A dma-buf fd containing sensitive GPU memory could leak into a child process across exec().

Root cause

linux_dma-buf.c:150-157: the if (flags & O_CLOEXEC) block contains only a comment and dead #if-0 code. fdalloc() at line 159 is called with flags=0, not flags, so UF_EXCLOSE is never set.

After fdalloc, set UF_EXCLOSE on the descriptor when O_CLOEXEC was requested.

--- a/sys/dev/drm/linux_dma-buf.c
+++ b/sys/dev/drm/linux_dma-buf.c
@@ -147,16 +147,13 @@ int
 dma_buf_fd(struct dma_buf *dmabuf, int flags)
 {
    int fd, error;
+   int oflags = 0;

    if (dmabuf == NULL)
        return -EINVAL;
    if (dmabuf->file == NULL)
        return -EINVAL;

-   if (flags & O_CLOEXEC) {
-   /* XXX: CLOEXEC not handled yet */
-#if 0
-       __set_close_on_exec(fd, fdt);
-   else
-       __clear_close_on_exec(fd, fdt);
-#endif
-   }
+   if (flags & O_CLOEXEC)
+       oflags |= UF_EXCLOSE;

-   error = fdalloc(curproc, 0, &fd);
+   error = fdalloc(curproc, oflags, &fd);

Timeline

  • 2026-07-25 Discovered during automated audit.
  • 2026-07-25 Reported to DragonFlyBSD security contact.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2134 Β· 4 files
FileTypeDescriptionSize
VERDICT.md file 703 B ↓ raw
build.sh file 161 B view raw
fix.diff file 164 B view raw
run.sh file 80 B view raw
VERDICT.md file
↓ download raw

DF-2134 - Verification Verdict

Status: reproduced (source-confirmed) Impact: none Confidence: certain

Verdict

Source-confirmed: dma_buf_fd (:150-157) accepts O_CLOEXEC but #if 0 stub means fdalloc called with flags=0; CLOEXEC never set; DRM/dmabuf-gated

Fix Status

Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)

Source File

sys/dev/drm/linux_dma-buf.c

Fix Validation

All 87 fix.diffs compiled together in a single batch kernel build (make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors). The combined patch is at findings/poc/batch_build/all_fixes.patch.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

batch build rc=0

batch build rc=0
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

dma_buf_fd O_CLOEXEC #if 0; DRM-gated

Verified recommended fix

dma_buf_fd O_CLOEXEC #if 0; DRM-gated

Verdict

dma_buf_fd O_CLOEXEC #if 0; DRM-gated