* [PATCH 1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio()
2025-11-13 13:40 [PATCH 0/3] Fixes for zoned changes in block/for-next Damien Le Moal
@ 2025-11-13 13:40 ` Damien Le Moal
2025-11-13 14:44 ` Christoph Hellwig
2025-11-13 13:40 ` [PATCH 2/3] block: fix NULL pointer dereference in disk_report_zones() Damien Le Moal
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Damien Le Moal @ 2025-11-13 13:40 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Shin'ichiro Kawasaki, Christoph Hellwig
For zoned block devices that do not need zone write plugs (e.g. most
device mapper devices that support zones), the disk hash table of zone
write plugs is NULL. For such devices, blk_zone_reset_all_bio_endio()
should not attempt to scan this has table as that causes a NULL pointer
dereference.
Fix this by checking that the disk does have zone write plugs using the
atomic counter. This is equivalent to checking for a non-NULL hash table
but has the advantage to also speed up the execution of
blk_zone_reset_all_bio_endio() for devices that do use zone write plugs
but do not have any plug in the hash table (e.g. a disk with only full
zones).
Fixes: efae226c2ef1 ("block: handle zone management operations completions")
Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
block/blk-zoned.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 85de45c3f6be..98c26af01e24 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -1118,17 +1118,20 @@ static void blk_zone_reset_all_bio_endio(struct bio *bio)
sector_t sector;
unsigned int i;
- /* Update the condition of all zone write plugs. */
- rcu_read_lock();
- for (i = 0; i < disk_zone_wplugs_hash_size(disk); i++) {
- hlist_for_each_entry_rcu(zwplug, &disk->zone_wplugs_hash[i],
- node) {
- spin_lock_irqsave(&zwplug->lock, flags);
- disk_zone_wplug_set_wp_offset(disk, zwplug, 0);
- spin_unlock_irqrestore(&zwplug->lock, flags);
+ if (atomic_read(&disk->nr_zone_wplugs)) {
+ /* Update the condition of all zone write plugs. */
+ rcu_read_lock();
+ for (i = 0; i < disk_zone_wplugs_hash_size(disk); i++) {
+ hlist_for_each_entry_rcu(zwplug,
+ &disk->zone_wplugs_hash[i],
+ node) {
+ spin_lock_irqsave(&zwplug->lock, flags);
+ disk_zone_wplug_set_wp_offset(disk, zwplug, 0);
+ spin_unlock_irqrestore(&zwplug->lock, flags);
+ }
}
+ rcu_read_unlock();
}
- rcu_read_unlock();
/* Update the cached zone conditions. */
for (sector = 0; sector < capacity;
--
2.51.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio()
2025-11-13 13:40 ` [PATCH 1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio() Damien Le Moal
@ 2025-11-13 14:44 ` Christoph Hellwig
0 siblings, 0 replies; 8+ messages in thread
From: Christoph Hellwig @ 2025-11-13 14:44 UTC (permalink / raw)
To: Damien Le Moal
Cc: Jens Axboe, linux-block, Shin'ichiro Kawasaki,
Christoph Hellwig
On Thu, Nov 13, 2025 at 10:40:26PM +0900, Damien Le Moal wrote:
> For zoned block devices that do not need zone write plugs (e.g. most
> device mapper devices that support zones), the disk hash table of zone
> write plugs is NULL. For such devices, blk_zone_reset_all_bio_endio()
> should not attempt to scan this has table as that causes a NULL pointer
> dereference.
>
> Fix this by checking that the disk does have zone write plugs using the
> atomic counter. This is equivalent to checking for a non-NULL hash table
> but has the advantage to also speed up the execution of
> blk_zone_reset_all_bio_endio() for devices that do use zone write plugs
> but do not have any plug in the hash table (e.g. a disk with only full
> zones).
>
> Fixes: efae226c2ef1 ("block: handle zone management operations completions")
> Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
although maybe factoring that loop into helper might be a tad cleaner?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] block: fix NULL pointer dereference in disk_report_zones()
2025-11-13 13:40 [PATCH 0/3] Fixes for zoned changes in block/for-next Damien Le Moal
2025-11-13 13:40 ` [PATCH 1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio() Damien Le Moal
@ 2025-11-13 13:40 ` Damien Le Moal
2025-11-13 14:45 ` Christoph Hellwig
2025-11-13 13:40 ` [PATCH 3/3] dm: fix zone reset all operation processing Damien Le Moal
2025-11-13 16:16 ` [PATCH 0/3] Fixes for zoned changes in block/for-next Jens Axboe
3 siblings, 1 reply; 8+ messages in thread
From: Damien Le Moal @ 2025-11-13 13:40 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Shin'ichiro Kawasaki, Christoph Hellwig
Commit 2284eec5053d ("block: introduce blkdev_get_zone_info()")
introduced the report_active field in struct blk_report_zones_args so
that open and closed zones can be reported with the condition
BLK_ZONE_COND_ACTIVE in the case of a cached report zone.
However, the args pointer to a struct blk_report_zones_args that is
passed to disk_report_zones() can be NULL, e.g. in the case of internal
report zones operations for device mapper zoned targets.
Fix disk_report_zones() to make sure to check that the args is not null
before updating a zone condition for cached zone reports.
Fixes: 2284eec5053d ("block: introduce blkdev_get_zone_info()")
Reported-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
block/blk-zoned.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 98c26af01e24..dcc295721c2c 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -854,7 +854,7 @@ static unsigned int disk_zone_wplug_sync_wp_offset(struct gendisk *disk,
int disk_report_zone(struct gendisk *disk, struct blk_zone *zone,
unsigned int idx, struct blk_report_zones_args *args)
{
- if (args->report_active) {
+ if (args && args->report_active) {
/*
* If we come here, then this is a report zones as a fallback
* for a cached report. So collapse the implicit open, explicit
--
2.51.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/3] dm: fix zone reset all operation processing
2025-11-13 13:40 [PATCH 0/3] Fixes for zoned changes in block/for-next Damien Le Moal
2025-11-13 13:40 ` [PATCH 1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio() Damien Le Moal
2025-11-13 13:40 ` [PATCH 2/3] block: fix NULL pointer dereference in disk_report_zones() Damien Le Moal
@ 2025-11-13 13:40 ` Damien Le Moal
2025-11-13 14:46 ` Christoph Hellwig
2025-11-13 16:16 ` [PATCH 0/3] Fixes for zoned changes in block/for-next Jens Axboe
3 siblings, 1 reply; 8+ messages in thread
From: Damien Le Moal @ 2025-11-13 13:40 UTC (permalink / raw)
To: Jens Axboe, linux-block; +Cc: Shin'ichiro Kawasaki, Christoph Hellwig
dm_zone_get_reset_bitmap() is used to generate a bitmap of the zones of
a zoned device target when a REQ_OP_ZONE_RESET_ALL request is being
processed. This bitmap is built by executing a zone report with a report
callback set to the function dm_zone_need_reset_cb() in struct
dm_report_zones_args. However, the cb callback pointer is not anymore
the same as the callback specified by callers of the
blkdev_report_zones() function. Rather, this is a DM internal callback
and report zones callback functions from blkdev_report_zones() are
passed using struct blk_report_zones_args, introduced with commit
db9aed869f34 ("block: introduce disk_report_zone()").
This commit changed the DM main report zones callback handler function
dm_report_zones_cb() to call the new disk_report_zone() so that callback
functions from blkdev_report_zones() are executed, and this change
resulted in the DM internal dm_zone_need_reset_cb() callback function to
not be executed anymore, turning any REQ_OP_ZONE_RESET_ALL request into
a no-op.
Fix this by calling in dm_report_zones_cb() the DM internal cb function
specified in struct dm_report_zones_args.
Fixes: db9aed869f34 ("block: introduce disk_report_zone()").
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
drivers/md/dm-zone.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/md/dm-zone.c b/drivers/md/dm-zone.c
index 984fb621b0e9..5a840c4ae316 100644
--- a/drivers/md/dm-zone.c
+++ b/drivers/md/dm-zone.c
@@ -113,6 +113,15 @@ static int dm_report_zones_cb(struct blk_zone *zone, unsigned int idx,
args->next_sector = zone->start + zone->len;
+ /* If we have an internal callback, call it first. */
+ if (args->cb) {
+ int ret;
+
+ ret = args->cb(zone, args->zone_idx, args->data);
+ if (ret)
+ return ret;
+ }
+
return disk_report_zone(args->disk, zone, args->zone_idx++,
args->rep_args);
}
--
2.51.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 0/3] Fixes for zoned changes in block/for-next
2025-11-13 13:40 [PATCH 0/3] Fixes for zoned changes in block/for-next Damien Le Moal
` (2 preceding siblings ...)
2025-11-13 13:40 ` [PATCH 3/3] dm: fix zone reset all operation processing Damien Le Moal
@ 2025-11-13 16:16 ` Jens Axboe
3 siblings, 0 replies; 8+ messages in thread
From: Jens Axboe @ 2025-11-13 16:16 UTC (permalink / raw)
To: linux-block, Damien Le Moal; +Cc: Shin'ichiro Kawasaki, Christoph Hellwig
On Thu, 13 Nov 2025 22:40:25 +0900, Damien Le Moal wrote:
> Jens,
>
> Here are 3 patches to fix 2 oops (NULL pointer dereference) and a device
> mapper regression all introduced by the recent changes to blk-zoned.c
> that are in block/for-next.
>
> These are relatively simple problems that should have been discovered
> right away during development. I overlooked them due to some issues (now
> fixed) with my test VM environment which was not always running the
> correct kernel.
>
> [...]
Applied, thanks!
[1/3] block: fix NULL pointer dereference in blk_zone_reset_all_bio_endio()
(no commit info)
[2/3] block: fix NULL pointer dereference in disk_report_zones()
(no commit info)
[3/3] dm: fix zone reset all operation processing
(no commit info)
Best regards,
--
Jens Axboe
^ permalink raw reply [flat|nested] 8+ messages in thread