⬢ DragonFlyBSD Kernel Audit
DF-3161 / run.log
← back to finding ↓ download raw
# DF-3161 run 1 — process-held fd (characterization/control)
$ sh umount_fifoleak.sh
== baseline ==
baseline connected-stream sockets: 4

== CONTROL: open fifo on tmpfs, close normally (no umount -f) ==
HOLDING /mnt/df3161/f fd=3
with fifo open: 6 (baseline+2; +2 expected)
RELEASED
after holder exit: 4 (baseline+0; 0 expected if no leak)

== BUG RUN: open fifo on tmpfs, umount -f, then close ==
HOLDING /mnt/df3161/f fd=3
with fifo open: 6 (baseline+2; +2 expected)
umount -f /mnt/df3161
RELEASED
kill: 941: No such process
after holder exit: 4 (baseline+0)
after 3s more:    4 (baseline+0)

== VERDICT ==
not_reproduced (ctrl delta=0 bug delta=0)

NOTE: the holder died DURING umount -f: dounmount(MNT_FORCE) sends SIGINT
to every process whose descriptors reference the mount
(sys/kern/vfs_syscalls.c:929-946, unmount_allproc_cb:769-790); the holder
exited, its close() ran cleanly through fifo_close (v_ops still fifo), so
the counters balanced and nothing leaked.  => the force-close loop never
ran for an active fifo.  Run 2 (SCM_RIGHTS) removes the holder.

# DF-3161 run 2 — fd pinned by a unix socket buffer (deterministic)
$ /tmp/leak_scm            (root, stock kernel #0)
baseline: 4 stream sockets
fifo-open (+2 expected): 6 stream sockets
fifo fd hidden in unix socket buffer; nobody owns it
umount -f /mnt/df3161b (takes ~13s while retries exhaust)...
umount rc=0
after umount -f + close (leak: stays +2): 6 stream sockets   <-- LEAK
done

console (vm.sh log):
  unmount(/mnt/df3161b): forced umount of "(null)" - 1 namecache refs, 1 mount refs
  unmount(/mnt/df3161b): (0xfffff80116ee7800): 1 namecache refs, 1 mount refs still present