mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Junzhe Yu <junzheyu1@gmail.com>
To: snitzer@kernel.org, mpatocka@redhat.com, bmarzins@redhat.com,
	agk@redhat.com
Cc: dm-devel@lists.linux.dev, linux-kernel@vger.kernel.org
Subject: [BUG] dm-integrity: dangling reboot notifier after resume vs remove race
Date: Sat, 18 Jul 2026 21:32:19 +0800	[thread overview]
Message-ID: <2582d759-1e99-4a31-9a1b-5eccf0af3891@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3800 bytes --]

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 <fuzzanything@gmail.com>

[-- Attachment #2: dm-integrity-notifier-uaf-repro.tar.gz --]
[-- Type: application/x-gzip, Size: 9366 bytes --]

             reply	other threads:[~2026-07-18 13:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-18 13:32 Junzhe Yu [this message]
2026-07-22 16:14 ` Mikulas Patocka
2026-07-23  1:19   ` Junzhe Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2582d759-1e99-4a31-9a1b-5eccf0af3891@gmail.com \
    --to=junzheyu1@gmail.com \
    --cc=agk@redhat.com \
    --cc=bmarzins@redhat.com \
    --cc=dm-devel@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpatocka@redhat.com \
    --cc=snitzer@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®