Each module now exposes an opt-in full-chain root-pop via --full-chain:
default --exploit behavior is unchanged (primitive-only, returns
EXPLOIT_FAIL). With --full-chain, after primitive lands, modules call
iamroot_finisher_modprobe_path() via a module-specific arb_write_fn
that re-uses the same trigger + slab groom to write a userspace
payload path into modprobe_path[], then exec a setuid bash dropped
by the kernel-invoked modprobe.
netfilter_xtcompat (+239): msg_msg m_list_next stride-seed FALLBACK
af_packet (+316): sk_buff data-pointer stride-seed FALLBACK
af_packet2 (+156): tp_reserve underflow + skb spray, LAST RESORT
nf_tables (+275): forged pipapo_elem with kaddr value-ptr
(Notselwyn offset 0x10), FALLBACK
cls_route4 (+251): msg_msg refill of UAF'd filter, FALLBACK
fuse_legacy (+291): m_ts overflow + MSG_COPY sanity gate,
FALLBACK (one of two modules with a real
post-write sanity check)
stackrot (+233): race-driver budget extended 3s → 30s when
--full-chain; honest <1% race-win/run
All seven honor verified-vs-claimed: arb_write_fn returns 0 for
"trigger structurally fired"; the shared finisher's setuid-bash
sentinel poll is the empirical arbiter. EXPLOIT_OK only when the
sentinel materializes within 3s of the modprobe_path trigger.
Build clean on Debian 6.12.86 (kctf-mgr); all 7 modules refuse
cleanly on both default and --full-chain paths via the existing
patched-kernel detect gate (short-circuits before the new branch).
netfilter_xtcompat (CVE-2021-22555): +597 LoC — Option B
Andy Nguyen's IPT_SO_SET_REPLACE 4-byte OOB write trigger;
msg_msg kmalloc-2k spray + sk_buff sidecar; MSG_COPY witness
+ slabinfo delta. No leak→modprobe_path chain (per-kernel
offsets refused), honest EXPLOIT_FAIL with continuation
roadmap.
stackrot (CVE-2023-3269): +619 LoC — Option C
Two-thread race driver (MAP_GROWSDOWN + mremap rotation vs
fork+fault) with cpu pinning + 3s budget; kmalloc-192 spray
for anon_vma/anon_vma_chain; race-iteration + signal
breadcrumb to /tmp/iamroot-stackrot.log. Honest reliability
note in module header: <1% race-win/run on a vulnerable
kernel — the public PoC averages minutes-to-hours and needs
a much wider VMA staging matrix to be reliable.
Both refuse cleanly on Debian 6.12.86 (kctf-mgr); build clean.
This closes out the detect-only → LPE port across the corpus.
All 22 registered modules now either fire a real primitive or
refuse honestly per the verified-vs-claimed bar.