From: Damien Le Moal <dlemoal@kernel.org>
To: Rik van Riel <riel@surriel.com>, Jens Axboe <axboe@kernel.dk>
Cc: Keith Busch <kbusch@kernel.org>,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: RFC PATCH] null_blk: fix UBSAN shift-out-of-bounds when zone_size is 0 or overflows
Date: Sat, 8 Aug 2026 08:56:14 -0700 [thread overview]
Message-ID: <b90e5ffd-9973-4a6f-b3b5-609cb7debf70@kernel.org> (raw)
In-Reply-To: <20260808114239.69167f68@fangorn>
On 2026/08/08 8:42, Rik van Riel wrote:
> null_zone_no() does sect >> ilog2(dev->zone_size_sects). When
> zone_size_sects is 0, ilog2(0) returns -1, producing shift exponent -1
> which UBSAN reports as shift-out-of-bounds.
>
> UBSAN: shift-out-of-bounds in drivers/block/null_blk/zoned.c:21:14
> shift exponent -1 is negative
> Call Trace:
> null_zone_no drivers/block/null_blk/zoned.c:21 [inline]
> null_process_zoned_cmd+0xf76/0xf80 drivers/block/null_blk/zoned.c:728
> null_handle_cmd drivers/block/null_blk/main.c:1455 [inline]
> null_queue_rq+0x8bc/0xe70 drivers/block/null_blk/main.c:1703
> __blk_mq_issue_directly block/blk-mq.c:2694 [inline]
> blk_mq_try_issue_directly+0x3f4/0x880 block/blk-mq.c:2754
> blk_mq_submit_bio+0x20c0/0x2a40 block/blk-mq.c:3208
> submit_bio_noacct_nocheck+0x2f4/0xa40 block/blk-core.c:790
> block_read_full_folio+0x7a6/0x810 fs/buffer.c:2463
> filemap_read_folio+0x12c/0x3a0 mm/filemap.c:2510
> read_part_sector+0xb6/0x2b0 block/partitions/core.c:724
> adfspart_check_ICS+0xb1/0x960 block/partitions/acorn.c:357
> check_partition block/partitions/core.c:143 [inline]
> blk_add_partitions block/partitions/core.c:591 [inline]
> bdev_disk_changed+0x851/0x17a0 block/partitions/core.c:695
> blkdev_get_whole+0x372/0x510 block/bdev.c:751
> add_disk_final block/genhd.c:412 [inline]
> add_disk_fwnode+0x24b/0x3a0 block/genhd.c:606
> null_add_dev+0x130b/0x1d70 drivers/block/null_blk/main.c:2052
> nullb_device_power_store+0x240/0x380 drivers/block/null_blk/main.c:501
> configfs_write_iter+0x337/0x430 fs/configfs/file.c:229
>
> Syzkaller triggers this by creating a zoned null_blk device via
> configfs. The Call Trace shows configfs_write_iter in configfs/file.c
> handling a write to power file, which calls nullb_device_power_store in
> main.c, which calls null_add_dev in main.c, which calls add_disk in
> genhd.c, which triggers partition scan via bdev_disk_changed in
> partitions/core.c.
>
> A zoned null_blk device with zone_size 0 should not be legal. Existing
> code tries to reject it via is_power_of_2() check in zoned.c and
> !zone_size check in main.c, but syzkaller can still reach
> null_zone_no() with zone_size_sects 0 via two paths:
>
> 1. Direct 0 via configfs: zone_size attribute store in main.c has
> NULLB_DEVICE_ATTR(zone_size, ulong, NULL) with no validation callback,
> so echo 0 > zone_size succeeds before power store. If zoned is false
> at power store time, the !zone_size check in main.c is skipped, and
> later zoned set true leaves zone_size 0.
>
> 2. Large value overflow: mb_to_sects() in zoned.c does
> (sector_t)mb * SZ_1M >> SECTOR_SHIFT which is mb * 2048. If mb is
> 1UL << 53 (9PB), mb * 2048 overflows 64-bit to 0. The value is
> power-of-two so is_power_of_2() passes, but mb_to_sects() returns 0.
>
> Check for zero zone_size explicitly in null_init_zoned_dev() in
> zoned.c, returning -EINVAL with "must be non-zero power-of-two".
> Check for zero zone_size_sects after mb_to_sects() conversion,
> returning -EINVAL for overflow case. Keep defensive check in
> null_zone_no() returning 0 for zero sectors to avoid shift out-of-bounds
> even if zero slips through.
>
> This change should be safe because zone_size is set once in
> null_init_zoned_dev() under device lock and never changes after, and 0
> is never valid for a zoned device. Returning -EINVAL at init time fails
> device creation early with clear error, while defensive return 0 in
> null_zone_no() makes zoned command fail via offline zone check.
> No new locking is introduced.
>
> Reported-by: syzbot+abd6a8dca0f2b7726060@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=abd6a8dca0f2b7726060
> Link: https://lore.kernel.org/all/6a75205c.01d0871a.3a0d52.0033.GAE@google.com/
> Fixes: 8a3cf049af68 ("null_blk: add zoned block device emulation")
> Cc: stable@vger.kernel.org
> Assisted-by: Hermes:muse-spark-1.2 syzkaller
> Signed-off-by: Rik van Riel <riel@surriel.com>
Looks good.
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
prev parent reply other threads:[~2026-08-08 15:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-08 15:42 RFC PATCH] null_blk: fix UBSAN shift-out-of-bounds when zone_size is 0 or overflows Rik van Riel
2026-08-08 15:56 ` Damien Le Moal [this message]
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=b90e5ffd-9973-4a6f-b3b5-609cb7debf70@kernel.org \
--to=dlemoal@kernel.org \
--cc=axboe@kernel.dk \
--cc=kbusch@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=riel@surriel.com \
/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