VYPR
Unrated severityNVD Advisory· Published Jun 9, 2026

CVE-2026-46327

CVE-2026-46327

Description

In the Linux kernel, the following vulnerability has been resolved:

dm: fix unlocked test for dm_suspended_md

The function dm_blk_report_zones tests if the device is suspended with the "dm_suspended_md" call. However, this function is called without holding any locks, so the device may be suspended just after it.

Move the call to dm_suspended_md after dm_get_live_table, so that the device can't be suspended after the suspended state was tested.

Affected products

1

Patches

8
d809a36692ee

dm: fix unlocked test for dm_suspended_md

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitMikulas PatockaFixed in 6.19.4via kernel-cna
1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index c95e417194b33..bc4e45862a220 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -60,11 +60,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -79,6 +81,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, nr_zones, &dm_args);
     	}
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
175ac0a61154

dm: fix unlocked test for dm_suspended_md

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitMikulas PatockaFixed in 6.12.75via kernel-cna
1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index 04cc36a9d5ca4..d7b1c89fcd87b 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -66,11 +66,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -80,6 +82,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb,
     					     data);
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
7a3385e97af2

dm: fix unlocked test for dm_suspended_md

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitMikulas PatockaFixed in 6.18.14via kernel-cna
1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index 78e17dd4d01b8..ba39c8313f32b 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -66,11 +66,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -80,6 +82,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb,
     					     data);
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
24c405fdbe21

dm: fix unlocked test for dm_suspended_md

1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index c95e417194b33..bc4e45862a220 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -60,11 +60,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -79,6 +81,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, nr_zones, &dm_args);
     	}
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
175ac0a61154

dm: fix unlocked test for dm_suspended_md

1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index 04cc36a9d5ca4..d7b1c89fcd87b 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -66,11 +66,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -80,6 +82,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb,
     					     data);
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
24c405fdbe21

dm: fix unlocked test for dm_suspended_md

1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index c95e417194b33..bc4e45862a220 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -60,11 +60,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -79,6 +81,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, nr_zones, &dm_args);
     	}
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
7a3385e97af2

dm: fix unlocked test for dm_suspended_md

1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index 78e17dd4d01b8..ba39c8313f32b 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -66,11 +66,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -80,6 +82,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, sector, nr_zones, cb,
     					     data);
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    
d809a36692ee

dm: fix unlocked test for dm_suspended_md

1 file changed · +6 4
  • drivers/md/dm-zone.c+6 4 modified
    diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
    index c95e417194b33..bc4e45862a220 100644
    --- a/drivers/md/dm-zone.c
    +++ b/drivers/md/dm-zone.c
    @@ -60,11 +60,13 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		 * Zone revalidation during __bind() is in progress, but this
     		 * call is from a different process
     		 */
    -		if (dm_suspended_md(md))
    -			return -EAGAIN;
    -
     		map = dm_get_live_table(md, &srcu_idx);
     		put_table = true;
    +
    +		if (dm_suspended_md(md)) {
    +			ret = -EAGAIN;
    +			goto do_put_table;
    +		}
     	} else {
     		/* Zone revalidation during __bind() */
     		map = zone_revalidate_map;
    @@ -79,6 +81,7 @@ int dm_blk_report_zones(struct gendisk *disk, sector_t sector,
     		ret = dm_blk_do_report_zones(md, map, nr_zones, &dm_args);
     	}
     
    +do_put_table:
     	if (put_table)
     		dm_put_live_table(md, srcu_idx);
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"The dm_blk_report_zones function checks if a device is suspended without holding necessary locks, allowing the device to be suspended between the check and subsequent operations."

Attack vector

An attacker can trigger this vulnerability by calling the dm_blk_report_zones function. The vulnerability occurs because the check for the device's suspended state, using dm_suspended_md, is performed without acquiring any locks. This allows a race condition where the device can be suspended by another process immediately after the check but before the device's live table is obtained.

Affected code

The vulnerability resides in the dm_blk_report_zones function within the drivers/md/dm-zone.c file. Specifically, the check for the device's suspended state using dm_suspended_md was performed before acquiring the necessary locks to access the device's table.

What the fix does

The patch moves the call to dm_suspended_md to occur after dm_get_live_table has been called and the lock has been acquired [patch_id=5357581]. This ensures that the device cannot be suspended between the check for its suspended state and the retrieval of its live table, thus preventing the race condition.

Generated on Jun 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1