DF-2209 / run_dmesg.log
DF22 RIG start: kernel-resident verbatim drm_sysfs.c add/remove (baseline) + fix.diff variants DF22 shims: kzalloc/kfree/kasprintf mirror slab.h:35,38 and drm_dragonfly.c:65-94 with fault injection ONLY at the cited call sites DF2208 CASE A (control): verbatim add/remove DF22 [drm_sysfs] adding "DP-1" to sysfs DF2208 ret=0 kdev=0xfffff80116c07a80 name='card0-DP-1' (content capture: card%d-%s of dev->primary->index=0, connector->name='DP-1') DF2208 offsetof(struct device, kobj.name)=8 sizeof(struct device)=56 (M_CACHEALIGN -> power-of-2 class) DF22 [drm_sysfs] removing "DP-1" from sysfs DF2208 after remove: connector->kdev still reads 0xfffff80116c07a80 (baseline remove NULLs nothing); alloc_events=2 free_events=1 (delta alloc=2 free=1) DF2208 SIDE-OBSERVATION: the kasprintf'd kobj.name string is never freed by remove() (drm_sysfs.c:52-53 frees kdev only) -> leaks 1 allocation per connector add/remove cycle DF2208 CASE B (kasprintf==NULL injected at drm_sysfs.c:40): DF22 [drm_sysfs] adding "DP-2" to sysfs DF2208 ret=0 kdev=0xfffff80116c07a80 kobj.name=0 DF2208 VERDICT: SILENT NULL PLANTED -- function reports SUCCESS (ret==0) with kdev->kobj.name==NULL; first consumer deref (intel_dp.c:5251 connector->kdev->kobj.name) hits NULL DF22 [drm_sysfs] removing "DP-2" from sysfs DF2209 CASE D (UAF cycle): verbatim add -> remove -> reclaim -> consume -> re-add -> remove DF22 [drm_sysfs] adding "DP-3" to sysfs DF2209 [1] add: kdev=0xfffff80116c07a80 (kobj.name='card0-DP-3') DF22 [drm_sysfs] removing "DP-3" from sysfs DF2209 [2] remove: kfree(0xfffff80116c07a80) done; connector->kdev still == 0xfffff80116c07a80 (DANGLING -- drm_sysfs.c:52-53 never NULLs it) DF2209 [3] reclaim: fresh kmalloc(56, M_DF22, M_WAITOK|M_CACHEALIGN|M_ZERO) returned 0xfffff80116c07a80 == freed A (IMMEDIATE SAME-ZONE REUSE); block poisoned 0x41 and kobj.name forged DF2209 [4] consumer read connector->kdev->kobj.name -> 'DF2209-PWNED-BY-RECLAIM' (UAF READ returns ATTACKER-CONTROLLED data; was 'card0-DP-3' before the free) DF2209 [5] re-add: ret==0 (SUCCESS) with rig_kzalloc_calls UNCHANGED (3) -- guard at drm_sysfs.c:35-36 turned add into a silent no-op on the DANGLING pointer DF22 [drm_sysfs] removing "DP-3" from sysfs DF2209 [6] second remove: production kfree()d the RECLAIMED live object 0xfffff80116c07a80 owned by another allocator (CROSS-OBJECT FREE); owner still holds the pointer DF2209 [6] owner-after-free read R->kobj.name -> 0xfffff8008f90d100 (== forged string, intact) DF2209 VERDICT: UAF CONFIRMED through verbatim drm_sysfs.c code (dangling ptr + silent re-add + controlled reclaim + cross-object free) DF2208 CASE E (fix.diff variants, same injections): DF2208 [kzalloc-NULL] ret=-12 (-ENOMEM) kdev=0 -- NO fault, caller (drm_connector.c:445-446) can fail loudly DF2208 [kasprintf-NULL] ret=-12 kdev=0 kobj.name=0 -- kdev freed and NULLed, NO silent NULL planted DF2209 CASE F (fix.diff variants): DF22 [drm_sysfs] adding "DP-5" to sysfs DF22 [drm_sysfs] removing "DP-5" from sysfs DF2209 [1] fixed remove: kdev=0 (NULLed: fix breaks the dangling pointer) DF22 [drm_sysfs] adding "DP-5" to sysfs DF2209 [2] fixed re-add: FRESH allocation 0xfffff80116c07b40 != freed 0xfffff80116c07a80 (and != interposed 0xfffff80116c07a80), kzalloc_calls 6 -> 7, name='card0-DP-5' -- no dangling, no silent no-op DF22 [drm_sysfs] removing "DP-5" from sysfs DF2209 VERDICT: fixed cycle clean DF22 RIG done (baseline kzalloc-NULL panic case ARMED: sysctl kern.df2208_fire=1)