# DF-5094 — vinum: unbounded daemon instantiation, pid-blind abdication; the
# plausible multi-consumer double-free is REFUTED on current DragonFly (MP token)

## What was claimed and what held

Claim investigated (pass-2 extension of DF-2103, which itself says "No mem
corruption"): `VINUM_DAEMON` (vinumioctl.c:296) starts `vinum_daemon()` with no
single-instance check; the "abdication" guard (vinumdaemon.c:83) compares
`curproc->p_pid` with the `daemonpid` stamp and only runs **after tsleep
returns** — so threads of one process (same pid) can never oust each other, and
a busy daemon never re-checks. With the dequeue at vinumdaemon.c:89-94 guarded
only by crit sections (no cross-CPU serialization *of the queue itself*), two
concurrent daemons should double-dequeue one `struct daemonq` element and
`Free()` it twice (vinumdaemon.c:177) → kernel heap double-free.

**What is real (certain, demonstrated on the guest):**
* any number of concurrent daemons can be instantiated — 3 ran at once;
* abdication is pid-based and lazy: same-process daemons are NEVER ousted;
* the daemons are permanent: `P_SYSTEM` + non-PCATCH `tsleep` → the host
  process becomes unkillable (`kill -9` leaves a D-state process — captured in
  `threadstate.txt`), aggravating the DF-4760 stop-wedge.

**What is refuted (certain, demonstrated on the guest):**
* the memory corruption. Every path that touches `daemonq` executes while
  holding the **MP token**:
  - consumers: `vinum_daemon()` runs inside the `VINUM_DAEMON`/`VINUM_FINDDAEMON`
    ioctl → `dev_doperate_ops()` takes `get_mplock()` because `vinum_ops` is
    NOT `D_MPSAFE` (vinum.c:58-70, kern_device.c:570-577). `tsleep` releases
    the token while asleep and reacquires it before returning, so the whole
    daemon loop body (dequeue, switch, `Free`) is token-serialized.
  - producers: `save_config()` from ioctls (token via the ioctl), the
    `daemonrq_ioerror` producer `complete_rqe()` explicitly `get_mplock()`
    (vinuminterrupt.c:75), `daemonrq_closedrive` from set_sd_state ioctls, and
    the `daemonrq_return` stop element from `free_vinum()` (module-event path).
  So the crit-only queue protection is redundant-but-safe in the current tree:
  the MP token is the real lock.

Empirical: two adversarial runs (3 daemon threads + 4 `VINUM_SAVECONFIG`
producer threads on a 6-CPU guest) pushed **27,798,967 + 18,707,189 ≈ 46.5M
elements** through the concurrent consumers with zero panics, zero slab/freelist
corruption messages, guest healthy afterwards (`run.log`, `run.2.log`).
Live thread states show the serialization directly: two daemons asleep on
wchan `vinum`, the third blocked on `mp_token` (`threadstate.txt`).

## Reproduce (root on the DragonFly guest)

```
kldload vinum
cc -O2 -pthread -o /tmp/df5094 /tmp/df5094_multidaemon.c   # or ./build.sh
/tmp/df5094 90                                               # or ./run.sh
```

Expected on this kernel: 3 concurrent daemons consume the storm cleanly, the
process becomes unkillable at exit, no panic — i.e. the corruption claim does
NOT reproduce; the unbounded-daemon / unkillable-process behavior DOES.

## Notes

* Note for DF-2103: the same MP-token invariant calls into question pass-1's
  "cross-CPU races lose/leak requests" impact on the current tree for the
  token-holding producers; the **lost-wakeup** liveness half of DF-2103
  (check-then-tsleep with no interlock, vinumdaemon.c:74-88) remains valid —
  token serialization does not fix lost wakeups.
* If vinum is ever converted to D_MPSAFE (or the daemon moved out of the ioctl
  context) without replacing crit sections with a real spinlock/mutex, this
  becomes the double-free described above — the PoC here is then the trigger.

## 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.

(No fix.diff for this item: documented recommendation only - see Fix above.)
