Hello, I am reporting a KASAN slab use-after-free in dm-integrity involving the reboot notifier registration path.
Summary ======= A late do_resume() can register ic->reboot_notifier on a dm_integrity_c object that a concurrent DM_DEV_REMOVE path is destroying. The removal path unregisters the old notifier via dm_integrity_postsuspend() and later frees ic in dm_integrity_dtr(), but does not unregister the notifier that the racing resume just installed. The global reboot notifier chain is then left with a dangling node; a later notifier_chain_register() walk touches it and panics under KASAN. Affected ======== - Confirmed on Linux 6.6.144 (da47cbc254661aa66d61ef061485a7080305c4be) - Originally found on Linux 6.6.0 (ffc253263a1375a65fa6c9f62a893e9767fbebfa) - Files: drivers/md/dm-integrity.c, drivers/md/dm-ioctl.c, kernel/notifier.c - Config: CONFIG_DM=y, CONFIG_DM_INTEGRITY=y, CONFIG_KASAN=y Root cause (brief) ================== 1. do_resume() in drivers/md/dm-ioctl.c resumes mapped device md without rechecking whether md has already entered the DMF_FREEING removal path. 2. Under the bad interleaving, removal has already unregistered the old ic->reboot_notifier through dm_integrity_postsuspend(). 3. The late do_resume() continues into dm_integrity_resume() and registers a new ic->reboot_notifier on the global reboot notifier chain. 4. Removal then frees this ic via dm_table_destroy() / dm_integrity_dtr(), but no second postsuspend() runs to unregister the newly registered notifier. 5. The chain retains a dangling notifier_block embedded in the freed ic. A later notifier_chain_register() walks the list to insert by priority, touches the freed node, and panics. Crash excerpt (KASAN) =====================BUG: KASAN: slab-use-after-free in notifier_chain_register+0x2aa/0x310 kernel/notifier.c:35
Call Trace: notifier_chain_register+0x2aa/0x310 blocking_notifier_chain_register+0x6e/0xc0 dm_integrity_resume+0x5a4/0x1a20 drivers/md/dm-integrity.c:3293 dm_table_resume_targets+0x1d5/0x350 dm_resume+0x19e/0x2b0 dev_suspend+0x543/0x7e0 Allocated by: dm_integrity_ctr -> table_load Freed by: dm_integrity_dtr -> __dm_destroy -> DM_DEV_REMOVE Full stack is in the attached tarball as stacktrace.txt. Impact ====== Privileged local DoS (CAP_SYS_ADMIN required to use /dev/mapper/control). dm-integrity is an optional target. The race can be hit reliably (especially with CPU-pinned workers), but we do not have a stable reclaim path to RIP control. We are reporting this as a low-risk privileged DoS / functional memory-safety bug, not as a high-severity exploit. Reproducer ========== Attached: dm-integrity-notifier-uaf-repro.tar.gz VM-only (do not run on a production host). Minimized PoC: concurrent DM_DEV_CREATE / DM_TABLE_LOAD (two integrity tables) / DM_DEV_SUSPEND (resume) / DM_DEV_REMOVE. Workers use sched_setaffinity to CPU 0; without CPU binding the race may miss on some hosts. Quick path (Docker + KVM): tar xzf dm-integrity-notifier-uaf-repro.tar.gz cd <extracted-dir> # contains Dockerfile, poc.c, repro.sh, ... docker build -t dm-integrity-uaf -f Dockerfile . mkdir -p artifacts docker run --rm --privileged --device=/dev/kvm --network=host \ -v "$PWD/artifacts:/artifacts" \ -e OUTPUT_DIR=/artifacts \ -e RUN_TIMEOUT_SEC=180 \ dm-integrity-uaf Expected within ~20-90s after the PoC starts (first run also builds the kernel): BUG: KASAN: slab-use-after-free in notifier_chain_register ... dm_integrity_resume ... Kernel panic - not syncing: KASAN: panic_on_warn set ... I am happy to test patches. Please let me know if you need more detail. Thanks, Yu Junzhe FuzzAnything <[email protected]>
dm-integrity-notifier-uaf-repro.tar.gz
Description: GNU Zip compressed data

