Re: [BUG] dm-integrity: dangling reboot notifier after resume vs remove race

Junzhe Yu <[email protected]> Thu, 23 Jul 2026 09:19:32 +0800
Newsgroups dev.linux.lists.dm-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi Mikulas,

Thanks for the suggested fix. We verified it on Linux 6.6.144 with KASAN
against our minimized PoC (resume racing remove / reboot-notifier UAF).

   if (!dm_suspended_md(md) || test_bit(DMF_FREEING, &md->flags))
           goto out;

Results:
   - unpatched: KASAN slab-use-after-free in notifier_chain_register via
     dm_integrity_resume within ~20s
   - with your change: no KASAN UAF for a 5-minute PoC window

Self-contained test package (patch + poc.c + A/B scripts + captured logs):

   dm-integrity-dm-resume-fix-test.tar.gz

Re-run with Docker (see README.md inside the tarball):

   docker build -t dm-integrity-patch-test -f Dockerfile .
   mkdir -p artifacts
   docker run --rm --privileged --device=/dev/kvm --network=host \
     -v "$PWD/artifacts:/artifacts" -e OUTPUT_DIR=/artifacts \
     dm-integrity-patch-test

Thanks,
Junzhe

On 7/23/2026 12:14 AM, Mikulas Patocka wrote:
>
> On Sat, 18 Jul 2026, Junzhe Yu wrote:
>
>> 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.
> Hi
>
> Does this patch fix it?
>
> Mikulas
>
>
> dm: fix resume-vs-remove race
>
> If the user issues the resume ioctl and the remove ioctl at the same
> time, it may be possible that the device is resumed after it is suspended
> in __dm_destroy. The result is that the table is destroyed without
> calling the postsuspend method.
>
> Dm targets expect that they may be removed only after the postsuspend
> method method was called. If we break this expectation, it can cause
> misbehavior in various targets. For example - in the dm-integrity target,
> the reboot notifier is not unregistered, leading to use-after-free.
>
> Fix this bug by refusing to resume if the device is being destroyed.
>
> Signed-off-by: Mikulas Patocka <[email protected]>
> Cc: [email protected]
>
> ---
>   drivers/md/dm.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> Index: linux-2.6/drivers/md/dm.c
> ===================================================================
> --- linux-2.6.orig/drivers/md/dm.c	2026-07-13 20:58:56.000000000 +0200
> +++ linux-2.6/drivers/md/dm.c	2026-07-22 17:40:29.000000000 +0200
> @@ -3140,7 +3140,7 @@ retry:
>   	r = -EINVAL;
>   	mutex_lock_nested(&md->suspend_lock, SINGLE_DEPTH_NESTING);
>   
> -	if (!dm_suspended_md(md))
> +	if (!dm_suspended_md(md) || test_bit(DMF_FREEING, &md->flags))
>   		goto out;
>   
>   	if (dm_suspended_internally_md(md)) {
>
dm-integrity-dm-resume-fix-test.tar.gz (application/x-gzip, 12.4 KB) - not displayed