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.
Recommended fix
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)
PoC verification
Evidence pack
findings/poc/DF-2134 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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 |
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
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
fixedbatch build rc=0
batch 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
No comments yet.