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

poll() silently truncates nfds to kern.maxfilesperproc*2 β€” ready descriptors beyond the clamp are dropped without error

Field Value
ID DF-2733
Status new
Severity Low
CVSS 3.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
CWE CWE-20
File sys/kern/sys_generic.c
Lines 1639-1640
Area kern
Confidence certain
Discovered 2026-08-30
Pass 2 (GLM 5.3 second pass)
Bucket base:kern
Reported pending
Known CVE none
CVE match novel

Summary

dopoll() clamps nfds to maxfilesperproc2 (65056 on this guest) instead of returning EINVAL; pollfd entries beyond the clamp are silently ignored. Demonstrated: the only ready descriptor (pipe with data) placed at index clamp+16 β†’ poll returns 0 with no error, while the same descriptor at index 5 returns 1. POSIX requires EINVAL when nfds exceeds the implementation limit. Silent truncation can hang daemons built for large poll sets; also latent signed-int overflow in maxfilesperproc2 if root sets it β‰₯ 2^30.

Replace the clamp with if (nfds > maxfilesperproc * 2) return (EINVAL); in dopoll().

Timeline

  • 2026-08-30 Discovered during pass-2 audit of sys_generic.c (GLM 5.3); silent-drop behavior verified on stock same run.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2733 Β· 6 files
FileTypeDescriptionSize
pollclamp.c β€” 1.9 KB view raw
run.log β€” 242 B view raw
run.2.log β€” 242 B view raw
build.sh β€” 41 B view raw
run.sh β€” 22 B view raw
env.txt β€” 150 B view raw

Fix verification

not_testable
per-fix-DF-2733

Confirmed kernel references

Detail

Evidence (decisive lines)

['run.log (ready fd idx 5 -> 1; idx clamp+16 -> 0)', 'run.2.log (independent boot, identical)']

PoC changes

written fresh for this pass (no seed)

Verified recommended fix

Return EINVAL when nfds exceeds maxfilesperproc*2 instead of silently truncating.

Verdict

dopoll() silently clamps nfds to 2*kern.maxfilesperproc (65056 on guest) instead of returning EINVAL; a demonstrably-ready descriptor placed at index clamp+16 is silently dropped (poll returns 0, errno 0) while the same descriptor at index 5 returns 1. POSIX requires EINVAL; silent truncation can hang applications built for large poll sets. Low severity (correctness).