# DF-2226 - Verification Verdict

**Status:** reproduced
**Impact:** none (hardening)
**Confidence:** certain

## Mechanism
_prop_dictionary_internalize accepts <key></key>: after decoding the key string there is no keylen>0 rejection (the code comment even says non-empty), so an empty keysym is interned. The invariant is only asserted on the OTHER side, in _prop_dict_keysym_externalize (_PROP_ASSERT(pdk_key[0] != 0), prop_dictionary.c:248) - a kernel INVARIANTS build panics there, the shipped userland lib (NDEBUG) silently emits <key></key>.

## Verdict
REPRODUCED on the stock guest: prop_dictionary_internalize of <plist><dict><key></key><string>x</string></dict></plist> returns a live dictionary and prop_dictionary_get(dict, empty) fetches the object (empty keysym interned). Externalize round-trips <key></key> through the whole plist layer. Kernel-side internalize of untrusted XML has no in-tree caller reachable by an unprivileged user (devd consumes kernel-EXTERNALIZED props, not the reverse), so impact is hardening: any future kernel-side internalize of untrusted dictionaries panics INVARIANTS builds at prop_dictionary.c:248. sys/libprop is shared verbatim with the userland libprop, so the userland library accepts the same degenerate dictionaries.

## Threat / reachability
Crafted plist XML fed to any libprop consumer (userland: today; kernel: if ever wired) - invariant violation / INVARIANTS panic; no unprivileged kernel path found.

## Privilege escalation assessment
n/a (library invariant hardening; no kernel entry point)

## Fix
Reject empty keys at internalize time (goto bad) so the invariant holds at ingestion instead of asserting at externalize.

## Kernel references
- `sys/libprop/prop_dictionary.c:1339`
- `sys/libprop/prop_dictionary.c:248`
- `sys/libprop/prop_dictionary.c:252`

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