]> git.ipfire.org Git - thirdparty/linux.git/commit
iomap: fix out-of-bounds bitmap_set() with zero-length range
authorZhang Yi <yi.zhang@huawei.com>
Tue, 14 Jul 2026 08:23:24 +0000 (16:23 +0800)
committerChristian Brauner <brauner@kernel.org>
Thu, 23 Jul 2026 09:26:28 +0000 (11:26 +0200)
commit9c7d8f7c8994c790fca501dc45ce66e7356cbe05
treed3718bd5cf223d4a186b9076077ddadb4a6c066b
parent7a6fd6b21d7e1737b40de1a210acf9e6a1e4d59e
iomap: fix out-of-bounds bitmap_set() with zero-length range

ifs_set_range_dirty() and ifs_set_range_uptodate() compute last_blk
as (off + len - 1) >> i_blkbits.  When off is 0 and len is 0, the
unsigned subtraction underflows to SIZE_MAX, producing a huge
last_blk and nr_blks value that causes bitmap_set() to write far
beyond the ifs->state allocation.

Regarding ifs_set_range_uptodate(), it is temporarily safe because len
cannot be passed in as 0. However, for ifs_set_range_dirty() this is
reachable from __iomap_write_end(): when copy_folio_from_iter_atomic()
returns 0 (e.g. user buffer fault) and the folio is already uptodate,
the guard at the top of __iomap_write_end() does not trigger because
!folio_test_uptodate() is false, and iomap_set_range_dirty() is called
with copied == 0.

Add a !len guard to both functions before the computation, so that a
zero-length range is a no-op.

Fixes: 4ce02c679722 ("iomap: Add per-block dirty state tracking to improve performance")
Cc: stable@vger.kernel.org # v6.6
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Link: https://patch.msgid.link/20260714082325.325163-5-yi.zhang@huaweicloud.com
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/iomap/buffered-io.c