* [PATCH 0/2] block/scsi: fix zones_cond out-of-bounds write on zone report
@ 2026-09-11 4:11 ZHOU Jiaxiang
2026-09-11 4:11 ` [PATCH 1/2] block: " ZHOU Jiaxiang
2026-09-11 4:11 ` [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones ZHOU Jiaxiang
0 siblings, 2 replies; 5+ messages in thread
From: ZHOU Jiaxiang @ 2026-09-11 4:11 UTC (permalink / raw)
To: Damien Le Moal, Jens Axboe; +Cc: linux-block, Martin K . Petersen, linux-scsi
blk_revalidate_disk_zones() sizes the zones_cond array from the disk
capacity and zone size, but the per-zone index used by
blk_revalidate_zone_cond() comes from the device-driven report_zones()
walk and is never checked against the array size. A device that reports
more zones than the array holds makes blk_zone_set_cond() write out of
bounds, one byte per extra zone.
A concrete way to reach it is a zone count that does not fit 32 bits:
both struct blk_revalidate_zone_args.nr_zones and struct
zoned_disk_info.nr_zones are unsigned int, so a disk advertising
2^32 + 1024 zones of one 512-byte logical block gets its count
truncated to 1024; the array is allocated for 1024 zones while the
report walk proceeds past index 1024.
This is structurally analogous to CVE-2025-40345 (a device-reported
value exceeding a capacity-derived table corrupts kernel heap) and,
like CVE-2024-47682, it is fed by target-supplied data in the sd
revalidation path. As in that report, note that sd also sits on network
transports (iSCSI/SRP/FCoE), so the malformed geometry can arrive from a
remote target, not only from a physically attached device.
Verified on commit 50d05c7c76c9 ("Merge tag 'landlock-7.3-rc3'
of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux"), which
is v7.3-rc2, using KASAN builds on x86_64 and arm64:
BUG: KASAN: slab-out-of-bounds in blk_revalidate_zone_cb
Write of size 1 ... 0 bytes to the right of allocated 1024-byte region
sd_probe -> sd_revalidate_disk -> sd_zbc_revalidate_zones
-> blk_revalidate_disk_zones -> sd_zbc_report_zones
-> blk_revalidate_zone_cb
I have a working reproducer (dummy_hcd + raw-gadget ZBC device and a
minimal initramfs) as well as a full privilege-escalation demonstration
built on the primitive. As this report is the product of AI-assisted
analysis I am treating it as public per
Documentation/process/security-bugs.rst; both are available privately on
request.
Patch 1/2 fixes the write site and the block-layer truncation, which
covers every blk_revalidate_disk_zones() caller (sd, nvme, virtio-blk,
dm, null_blk, ublk, zloop). Patch 2/2 makes the SCSI path reject such
devices cleanly at scan time, before the truncated count reaches the
block layer.
Before the series the reproducer triggers the KASAN report above and the
escalation demonstration reaches a root shell from uid 1000. After the
series the device is rejected ("Too many zones"), there is no KASAN
report, and the demonstration no longer progresses. Each layer was also
verified independently (block-layer guard alone, and the write-site
check alone).
ZHOU Jiaxiang (2):
block: fix zones_cond out-of-bounds write on zone report
scsi: sd_zbc: reject disks with too many zones
block/blk-zoned.c | 15 +++++++++++++--
drivers/scsi/sd_zbc.c | 11 ++++++++++-
2 files changed, 23 insertions(+), 3 deletions(-)
--
2.34.1
[https://www.polyu.edu.hk/emaildisclaimer/PolyU_Email_Signature-v2.jpg]
Disclaimer:
This message (including any attachments) contains confidential information intended for a specific individual and purpose. If you are not the intended recipient, you should delete this message and notify the sender and The Hong Kong Polytechnic University (the University) immediately. Any disclosure, copying, or distribution of this message, or the taking of any action based on it, is strictly prohibited and may be unlawful.
The University specifically denies any responsibility for the accuracy or quality of information obtained through University E-mail Facilities. Any views and opinions expressed are only those of the author(s) and do not necessarily represent those of the University and the University accepts no liability whatsoever for any losses or damages incurred or caused to any party as a result of the use of such information.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] block: fix zones_cond out-of-bounds write on zone report
2026-09-11 4:11 [PATCH 0/2] block/scsi: fix zones_cond out-of-bounds write on zone report ZHOU Jiaxiang
@ 2026-09-11 4:11 ` ZHOU Jiaxiang
2026-09-11 8:13 ` Damien Le Moal
2026-09-11 4:11 ` [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones ZHOU Jiaxiang
1 sibling, 1 reply; 5+ messages in thread
From: ZHOU Jiaxiang @ 2026-09-11 4:11 UTC (permalink / raw)
To: Damien Le Moal, Jens Axboe; +Cc: linux-block, Martin K . Petersen, linux-scsi
blk_revalidate_disk_zones() sizes the zones_cond array from the disk
capacity and zone size, but the index used by blk_revalidate_zone_cond()
comes from the device-driven report_zones() walk and is never checked
against the array size. A device reporting more zones than fit the
array makes blk_zone_set_cond() write out of bounds.
One way to reach this is a zone count exceeding 32 bits: both
blk_revalidate_zone_args.nr_zones and struct zoned_disk_info.nr_zones
are unsigned int, so a disk advertising more than UINT_MAX zones (e.g.
2^32 + 1024 zones of one 512-byte logical block) gets its zone count
truncated to a small value, undersizing the array while the report
walk keeps counting upward.
Check the index against the array size before storing the zone
condition, and refuse to revalidate when the zone count does not fit
32 bits.
Fixes: 6e945ffb6555 ("block: use zone condition to determine conventional zones")
Signed-off-by: ZHOU Jiaxiang <26066541r@connect.polyu.hk>
---
block/blk-zoned.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index a5afb842bf35e..475aa16bc41a5 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -2018,12 +2018,17 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
struct blk_revalidate_zone_args *args)
{
struct queue_limits *lim = &disk->queue->limits;
+ unsigned long long nr_zones;
unsigned int pool_size;
int ret = 0;
args->disk = disk;
- args->nr_zones =
- DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors);
+ nr_zones = DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors);
+ if (nr_zones > UINT_MAX) {
+ pr_warn("%s: Too many zones (%llu)\n", disk->disk_name, nr_zones);
+ return -EINVAL;
+ }
+ args->nr_zones = nr_zones;
/* Cached zone conditions: 1 byte per zone */
args->zones_cond = kzalloc(args->nr_zones, GFP_NOIO);
@@ -2131,6 +2136,12 @@ static int blk_revalidate_zone_cond(struct blk_zone *zone, unsigned int idx,
{
enum blk_zone_cond cond = zone->cond;
+ if (idx >= args->nr_zones) {
+ pr_warn("%s: Zone report index %u exceeds zone count %u\n",
+ args->disk->disk_name, idx, args->nr_zones);
+ return -EINVAL;
+ }
+
/* Check that the zone condition is consistent with the zone type. */
switch (cond) {
case BLK_ZONE_COND_NOT_WP:
--
2.34.1
[https://www.polyu.edu.hk/emaildisclaimer/PolyU_Email_Signature-v2.jpg]
Disclaimer:
This message (including any attachments) contains confidential information intended for a specific individual and purpose. If you are not the intended recipient, you should delete this message and notify the sender and The Hong Kong Polytechnic University (the University) immediately. Any disclosure, copying, or distribution of this message, or the taking of any action based on it, is strictly prohibited and may be unlawful.
The University specifically denies any responsibility for the accuracy or quality of information obtained through University E-mail Facilities. Any views and opinions expressed are only those of the author(s) and do not necessarily represent those of the University and the University accepts no liability whatsoever for any losses or damages incurred or caused to any party as a result of the use of such information.
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones
2026-09-11 4:11 [PATCH 0/2] block/scsi: fix zones_cond out-of-bounds write on zone report ZHOU Jiaxiang
2026-09-11 4:11 ` [PATCH 1/2] block: " ZHOU Jiaxiang
@ 2026-09-11 4:11 ` ZHOU Jiaxiang
2026-09-11 8:11 ` Damien Le Moal
1 sibling, 1 reply; 5+ messages in thread
From: ZHOU Jiaxiang @ 2026-09-11 4:11 UTC (permalink / raw)
To: Damien Le Moal, Jens Axboe; +Cc: linux-block, Martin K . Petersen, linux-scsi
sd_zbc_read_zones() computes the number of zones with 64-bit
arithmetic and stores the result in the unsigned int nr_zones field
of struct zoned_disk_info, silently truncating counts that exceed 32
bits. The truncated count is later used to size per-zone resources,
while the device may still report more zones than fit.
Reject such devices at scan time: more than 4 billion zones is not
realistic for any medium that exists today, and accepting the
truncated count produces inconsistent zone bookkeeping.
Signed-off-by: ZHOU Jiaxiang <26066541r@connect.polyu.hk>
---
drivers/scsi/sd_zbc.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 56e455fb5addd..446628cb3db02 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -589,6 +589,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
u8 buf[SD_BUF_SIZE])
{
+ unsigned long long nr_zones64;
unsigned int nr_zones;
u32 zone_blocks = 0;
int ret;
@@ -620,7 +621,15 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
if (ret != 0)
goto err;
- nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
+ nr_zones64 = round_up(sdkp->capacity, zone_blocks) >>
+ ilog2(zone_blocks);
+ if (nr_zones64 > UINT_MAX) {
+ sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n",
+ nr_zones64);
+ ret = -EINVAL;
+ goto err;
+ }
+ nr_zones = nr_zones64;
sdkp->early_zone_info.nr_zones = nr_zones;
sdkp->early_zone_info.zone_blocks = zone_blocks;
--
2.34.1
[https://www.polyu.edu.hk/emaildisclaimer/PolyU_Email_Signature-v2.jpg]
Disclaimer:
This message (including any attachments) contains confidential information intended for a specific individual and purpose. If you are not the intended recipient, you should delete this message and notify the sender and The Hong Kong Polytechnic University (the University) immediately. Any disclosure, copying, or distribution of this message, or the taking of any action based on it, is strictly prohibited and may be unlawful.
The University specifically denies any responsibility for the accuracy or quality of information obtained through University E-mail Facilities. Any views and opinions expressed are only those of the author(s) and do not necessarily represent those of the University and the University accepts no liability whatsoever for any losses or damages incurred or caused to any party as a result of the use of such information.
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones
2026-09-11 4:11 ` [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones ZHOU Jiaxiang
@ 2026-09-11 8:11 ` Damien Le Moal
0 siblings, 0 replies; 5+ messages in thread
From: Damien Le Moal @ 2026-09-11 8:11 UTC (permalink / raw)
To: ZHOU Jiaxiang, Jens Axboe; +Cc: linux-block, Martin K . Petersen, linux-scsi
On 9/11/26 13:11, ZHOU Jiaxiang wrote:
> sd_zbc_read_zones() computes the number of zones with 64-bit
> arithmetic and stores the result in the unsigned int nr_zones field
> of struct zoned_disk_info, silently truncating counts that exceed 32
> bits. The truncated count is later used to size per-zone resources,
> while the device may still report more zones than fit.
>
> Reject such devices at scan time: more than 4 billion zones is not
> realistic for any medium that exists today, and accepting the
> truncated count produces inconsistent zone bookkeeping.
>
> Signed-off-by: ZHOU Jiaxiang <26066541r@connect.polyu.hk>
> ---
> drivers/scsi/sd_zbc.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
> index 56e455fb5addd..446628cb3db02 100644
> --- a/drivers/scsi/sd_zbc.c
> +++ b/drivers/scsi/sd_zbc.c
> @@ -589,6 +589,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
> int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
> u8 buf[SD_BUF_SIZE])
> {
> + unsigned long long nr_zones64;
> unsigned int nr_zones;
Keep the name nr_zones and drop the unsigned int nr_zones variable, it is not
needed.
> u32 zone_blocks = 0;
> int ret;
> @@ -620,7 +621,15 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
> if (ret != 0)
> goto err;
>
> - nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
> + nr_zones64 = round_up(sdkp->capacity, zone_blocks) >>
> + ilog2(zone_blocks);
> + if (nr_zones64 > UINT_MAX) {
> + sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n",
> + nr_zones64);
> + ret = -EINVAL;
> + goto err;
> + }
> + nr_zones = nr_zones64;
> sdkp->early_zone_info.nr_zones = nr_zones;
> sdkp->early_zone_info.zone_blocks = zone_blocks;
>
> --
> 2.34.1
>
> [https://www.polyu.edu.hk/emaildisclaimer/PolyU_Email_Signature-v2.jpg]
>
> Disclaimer:
>
> This message (including any attachments) contains confidential information intended for a specific individual and purpose. If you are not the intended recipient, you should delete this message and notify the sender and The Hong Kong Polytechnic University (the University) immediately. Any disclosure, copying, or distribution of this message, or the taking of any action based on it, is strictly prohibited and may be unlawful.
>
> The University specifically denies any responsibility for the accuracy or quality of information obtained through University E-mail Facilities. Any views and opinions expressed are only those of the author(s) and do not necessarily represent those of the University and the University accepts no liability whatsoever for any losses or damages incurred or caused to any party as a result of the use of such information.
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] block: fix zones_cond out-of-bounds write on zone report
2026-09-11 4:11 ` [PATCH 1/2] block: " ZHOU Jiaxiang
@ 2026-09-11 8:13 ` Damien Le Moal
0 siblings, 0 replies; 5+ messages in thread
From: Damien Le Moal @ 2026-09-11 8:13 UTC (permalink / raw)
To: ZHOU Jiaxiang, Jens Axboe; +Cc: linux-block, Martin K . Petersen, linux-scsi
On 9/11/26 13:11, ZHOU Jiaxiang wrote:
> blk_revalidate_disk_zones() sizes the zones_cond array from the disk
> capacity and zone size, but the index used by blk_revalidate_zone_cond()
> comes from the device-driven report_zones() walk and is never checked
> against the array size. A device reporting more zones than fit the
> array makes blk_zone_set_cond() write out of bounds.
>
> One way to reach this is a zone count exceeding 32 bits: both
> blk_revalidate_zone_args.nr_zones and struct zoned_disk_info.nr_zones
> are unsigned int, so a disk advertising more than UINT_MAX zones (e.g.
> 2^32 + 1024 zones of one 512-byte logical block) gets its zone count
> truncated to a small value, undersizing the array while the report
> walk keeps counting upward.
>
> Check the index against the array size before storing the zone
> condition, and refuse to revalidate when the zone count does not fit
> 32 bits.
>
> Fixes: 6e945ffb6555 ("block: use zone condition to determine conventional zones")
> Signed-off-by: ZHOU Jiaxiang <26066541r@connect.polyu.hk>
Looks OK.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-11 8:13 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11 4:11 [PATCH 0/2] block/scsi: fix zones_cond out-of-bounds write on zone report ZHOU Jiaxiang
2026-09-11 4:11 ` [PATCH 1/2] block: " ZHOU Jiaxiang
2026-09-11 8:13 ` Damien Le Moal
2026-09-11 4:11 ` [PATCH 2/2] scsi: sd_zbc: reject disks with too many zones ZHOU Jiaxiang
2026-09-11 8:11 ` Damien Le Moal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox