# DF-5482 VERDICT — efi_enter/efi_leave reentrancy landmine (latent)

**Status: untested (Info hardening class; no reachable nested path exists
today — nothing to reproduce by construction).**

## Trace

1. `lockinit(&efi_lock, "efi", 0, LK_CANRECURSE)` (efirt.c:396) — nested
   acquisition by the same thread is permitted.
2. Nested `efi_enter()` (same thread): `efi_savevm =
   td->td_lwp->lwp_vmspace` (efirt.c:352) now stores **efi_vmspace**
   (set by the outer entry via pmap_setlwpvm), destroying the saved
   user context.
3. Inner `efi_leave()`: `pmap_setlwpvm(td->td_lwp, efi_savevm)` restores
   efi_vmspace onto itself; `efi_savevm = NULL` (efirt.c:367-370).
4. Outer `efi_leave()`: `pmap_setlwpvm(td->td_lwp, NULL)` →
   `lp->lwp_vmspace = NULL` (pmap.c:6408) → `pmap =
   vmspace_pmap(newvm)` (pmap.c:6410) dereferences NULL → panic.

No current caller nests (all six entry points wrap one efi_enter; the
firmware cannot call back into the kernel), so this is latent. The
mismatch between the lock advertising recursion and the save/restore
machinery being single-flight is the defect; simplest fix: drop
LK_CANRECURSE from efi_lock so any future nesting fails loudly at
development time (or add a per-thread depth counter).

## Verification

None possible/needed: the trigger path does not exist in the current
call graph (verified by reading all callers of efi_enter: efirt.c:496,
525, 540, 569, 584, 600 — each wrapped once, no nesting possible from
firmware side). Filed as Info so the landmine is on record.

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