# DF-4301 verdict

## Reproduced?
No — latent by construction: triggering requires a KBDIO_UNLOADING
callback that returns an error, and both in-tree registrars (kbdmux.c:206-227,
syscons.c:891-900) unconditionally release and return 0. Status `untested`.

## Root cause (path:line)
- sys/dev/misc/vkbd/vkbd.c:848 — `kbd_unregister(kbd);` return ignored.
- sys/dev/misc/vkbd/vkbd.c:850-857 — unconditional kfree of state/keymaps/kbd.
- sys/dev/misc/kbd/kbd.c:268-277 — the EBUSY path the caller must honor.

## Impact
If any keyboard consumer refuses KBDIO_UNLOADING (or the kbd index is
inconsistent), the vkbd control fd's close path frees a keyboard that is
still registered in keyboard[]/kbdsw[] and still held BUSY by the
consumer: use-after-free on the next kbdsw dispatch (console input).
Root-triggered (0600 device) + needs a refusing consumer → Low,
speculative.

## Fix
```diff
--- a/sys/dev/misc/vkbd/vkbd.c
+++ b/sys/dev/misc/vkbd/vkbd.c
@@ -845,7 +845,10 @@ vkbd_term(keyboard_t *kbd)
 	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
 
-	kbd_unregister(kbd);
+	if (kbd_unregister(kbd) != 0)
+		return (EBUSY);	/* still registered/busy: do not free */
```

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