devfs_allocv failure ignored: devfs_spec_open and devfs_vop_nlookupdotdot use the vp unconditionally β vn_unlock(NULL)/NULL-fp panic under vnode exhaustion
| Field | Value |
|---|---|
| ID | DF-3020 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-476 |
| File | sys/vfs/devfs/devfs_vnops.c |
| Lines | 535-536, 933-978 (contrast :507) |
| Area | vfs/devfs |
| Confidence | speculative |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | memcorrupt |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
devfs_allocv can return an error leaving vpp=NULL. devfs_vop_nlookupdotdot:535-536 then vn_unlock(a_vpp) on NULL; in devfs_spec_open's clone path the (ignored) failure leaves vp=NULL, ap->a_vp=NULL, and :978 vn_unlock(vp=NULL) β kernel NULL-deref panic. Requires getnewvnode/vget failure β forceable via vnode-cache exhaustion pressure by an unprivileged user, otherwise rare; impact is a panic. Not executed (exhaustion setup time-heavy); code-path direct. Fix: check devfs_allocv's return (bail ENOENT in nlookupdotdot; treat clone allocv failure as failed clone in spec_open).
Timeline
- 2026-09-02 Discovered during pass-2 audit of devfs_vnops.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3020 Β· 9 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 323 B | β raw | |
| VERDICT.md | β | 1.3 KB | β raw | |
| df3020.c | β | 853 B | view raw | |
| df3020b.c | β | 1.0 KB | view raw | |
| env.txt | β | 248 B | view raw | |
| fix.diff | β | 145 B | view raw | |
| manifest.json | β | 597 B | view raw | |
| run.log | β | 256 B | view raw | |
| verdict.json | β | 1.6 KB | view raw |
DF-3020 - devfs_allocv failure ignored -> vn_unlock(NULL) panic under vnode exhaustion
Severity Low | verdict: not_reproduced | impact: none
Reproduce
Sources in this directory; build with cc -O2 -o <bin> <src> -pthread on the guest.
See VERDICT.md for the full narrative and run.log for the decisive output.
DF-3020 verification
Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64
Two attempts to force getnewvnode failure inside the ptmx clone path: (1) kern.maxvnodes=300 with 217,405 open/close cycles - zero failures, vnlru kept recycling; (2) kern.maxvnodes=120 while holding 1,001 ptmx fds open - further opens fail with ENODEV from the pty driver unit limit (bitmap exhausted near 1000 units), which fires inside the clone handler BEFORE devfs_allocv, so the ignored-error path is never reached. The NULL-deref code path is real (devfs_allocv can return error leaving *vpp NULL; devfs_vop_nlookupdotdot:535 and devfs_spec_open:933 ignore the return) but getnewvnode could not be made to fail from unprivileged pressure on this guest.
Kernel references
Fix
See fix.diff.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md + run.log + sources
PoC changes
adjusted from finding sketch to guest syscall/layout reality
Verified recommended fix
diff: check devfs_allocv return in devfs_vop_nlookupdotdot (bail ENOENT) and in devfs_spec_open clone path (treat as failed clone, vput orig).
Verdict
Two attempts to force getnewvnode failure inside the ptmx clone path: (1) kern.maxvnodes=300 with 217,405 open/close cycles - zero failures, vnlru kept recycling; (2) kern.maxvnodes=120 while holding 1,001 ptmx fds open - further opens fail with ENODEV from the pty driver unit limit (bitmap exhausted near 1000 units), which fires inside the clone handler BEFORE devfs_allocv, so the ignored-error path is never reached. The NULL-deref code path is real (devfs_allocv can return error leaving *vpp NULL; devfs_vop_nlookupdotdot:535 and devfs_spec_open:933 ignore the return) but getnewvnode could not be made to fail from unprivileged pressure on this guest.
No comments yet.