mirror of
https://github.com/RhapsodiOS/RhapsodiOS.git
synced 2026-11-03 22:01:40 -07:00
[GH-ISSUE #84] kernel: exec of a file that a forced unmount reclaims faults in vnode_pager_setup on a NULL v_vm_info #78
Labels
No labels
bug
documentation
enhancement
enhancement
good first issue
help wanted
help wanted
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/RhapsodiOS#78
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @raynorpat on GitHub (Oct 30, 2026).
Original GitHub issue: https://github.com/RhapsodiOS/RhapsodiOS/issues/84
Found by the #81 work: probe scenario S4 on branch issue-81-probe-fix, kernel cksum 370498376, log
vm/work/issue-81/pfix-all-com2.log.Symptom
A process execs a binary from an NFS (or other) mount while
umount -freclaims that vnode. The kernel traps:vnode_pager_setupreadsvp->v_vm_info->pagerwithv_vm_infoNULL.Where
kern/mach_loader.c~249 callsvnode_pager_setup(vp, FALSE, TRUE)on the exec'd vnode with no check that the vnode is still live.vm/vnode_pager.c~640-668 createsv_vm_infoonly under!MACH_NBC. With MACH_NBC it assumes it exists, and dereferencesv_vm_info->pagerboth before and aftervnode_pager_create, which can block.vclean→vm_info_free) running while exec blocks in between leavesv_vm_infoNULL. The vnode becomes a dead (VBAD) vnode.unmap_vnodein exec faulted first on the same NULL. The #81 fix now skips a reclaimed vnode there, so exec gets as far as the pager.Expected
An exec racing a forced unmount fails cleanly (ENOENT, EBADF or LOAD_FAILURE → the exec returns an error) instead of faulting. The same applies to the other
vnode_pager_setupcallers (mmap of a file, swap files).@raynorpat commented on GitHub (Oct 30, 2026):
Fixed by
eba20b6c5, merged into ffs-perf ina2a72069f(on top of #81).Root cause:
kern_exec.c:258) but keeps using it. Aumount -fcan run vclean, which freesv_vm_info(vfs_subr.c:1254-1257).parse_machfilethen callsvnode_pager_setup(mach_loader.c:249), which readsv_vm_info->pagerat entry, aftervnode_pager_create(which can block inzallocandVOP_GETATTR), and on return (vnode_pager.c:645/658/668).parse_machfilealso readsvnode_sizeagain at :309.Fix:
vnode_pager_setupreturnsvm_pager_nullwhen the vnode was reclaimed at entry or while it blocked. Every caller handles that:mach_loader.c):LOAD_FAILURE, so the user sees EBADEXEC (85).vnode_sizeis read once, right after setup.kern_mman.c:342): EBADF.map_vnode(mapfs.c): drops its pin on an orphaned vm_info.Also:
vnode_pager_createfrees a vstruct that was never published if the vnode was reclaimed duringzalloc.vnode_pageinnull-checksv_vm_info, so a fault on a reclaimed mapped file gets SIGBUS instead of a panic.Verified:
_vm_pager_get+0x18).error 85, no trap.rp.sh×3 andrp2.sh×3 rc=0.check-proc,check-mmap,check-vmpass on UFS and NFS, and the NFS plain unmount is clean.Left open:
VOP_GETATTRinvnode_pager_create.vnode_pageoutstill readsv_vm_info->vnode_sizeunchecked (~850).parse_machfilepages in its load commands wasn't reproduced.vnode_pager_setupstill skipsunix_release.