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

sys_fhopen() returns success (error=0) without valid file descriptor when regular file vnode lacks VM object

Summary

In sys_fhopen after VOP_OPEN succeeds if vnode is VREG but vp->v_object==NULL code prints warning jumps to bad_drop without setting error code. bad_drop clears descriptor drops file falls through to bad/done returns error=0 success. sysmsg_result never set to valid fd so caller receives success but has no open file descriptor result register contains whatever syscall framework left (typically 0 stdin). [VERIFIED pass2: reproduced WORSE than filed - crafted UDF image plus unpriv fhopen hits vn_close under locked vp panic lockmgr locking against myself, deterministic; UPGRADE Low to Medium (deterministic unprivileged kernel panic); EINVAL fix A/B survives]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2551 Β· 2 files
FileTypeDescriptionSize
fhopen_probe.c β€” 1.5 KB view raw
gen_udf.py β€” 7.1 KB view raw

Fix verification

not_testable
↓ fix.diffper-fix-DF-2551

Confirmed kernel references

Detail

Evidence (decisive lines)

panic.txt (fhopen: regular file did not have VM object + lockmgr panic, trace vn_close<-fdrop<-sys_fhopen); gen_udf.py builds the mounting UDF image

PoC changes

UDF image hand-crafted to DFlys parser (no mkfs tool exists); fhopen_probe driver

Verified recommended fix

set error=EINVAL and fp->f_ops=&badfileops before bad_drop (in combined fix kernel)

Verdict

sys_fhopens VREG-without-VM-object branch (vfs_syscalls.c:4933-4941) jumps to bad_drop with error still 0. Live on the STOCK kernel: udf is the one filesystem that sets v_type=VREG without vinitvmio/v_object anywhere (udf_vfsops.c:558 + zero v_object references in sys/vfs/udf/), and it implements vfs_fhtovp. A hand-crafted minimal UDF image (generator in pack) mounts cleanly; fhopen(O_RDONLY) of its regular file printed fhopen: regular file did not have VM object and then PANICKED: panic: lockmgr: locking against myself in vn_close<-fdrop<-sys_fhopen -- bad_drop drops the falloc reference while the vnode is still locked (VOP_OPEN had already installed vnode_fileops). Worse than the filed success-without-fd: on INVARIANTS it is a deterministic panic; without, a permanent self-deadlock. fhopen is an unprivileged syscall once the fs is mounted (also mountable with vfs.usermount=1). Controls: hammer2/tmpfs/cd9660 files all fhopen to valid fds.