linux-stable/block
Darrick J. Wong 64f505b08e block: fix race between set_blocksize and read paths
[ Upstream commit c0e473a0d2 ]

With the new large sector size support, it's now the case that
set_blocksize can change i_blksize and the folio order in a manner that
conflicts with a concurrent reader and causes a kernel crash.

Specifically, let's say that udev-worker calls libblkid to detect the
labels on a block device.  The read call can create an order-0 folio to
read the first 4096 bytes from the disk.  But then udev is preempted.

Next, someone tries to mount an 8k-sectorsize filesystem from the same
block device.  The filesystem calls set_blksize, which sets i_blksize to
8192 and the minimum folio order to 1.

Now udev resumes, still holding the order-0 folio it allocated.  It then
tries to schedule a read bio and do_mpage_readahead tries to create
bufferheads for the folio.  Unfortunately, blocks_per_folio == 0 because
the page size is 4096 but the blocksize is 8192 so no bufferheads are
attached and the bh walk never sets bdev.  We then submit the bio with a
NULL block device and crash.

Therefore, truncate the page cache after flushing but before updating
i_blksize.  However, that's not enough -- we also need to lock out file
IO and page faults during the update.  Take both the i_rwsem and the
invalidate_lock in exclusive mode for invalidations, and in shared mode
for read/write operations.

I don't know if this is the correct fix, but xfs/259 found it.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Link: https://lore.kernel.org/r/174543795699.4139148.2086129139322431423.stgit@frogsfrogsfrogs
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-05-29 11:02:01 +02:00
..
partitions block: fix conversion of GPT partition name to 7-bit 2025-03-13 13:01:58 +01:00
badblocks.c
bdev.c block: fix race between set_blocksize and read paths 2025-05-29 11:02:01 +02:00
bfq-cgroup.c
bfq-iosched.c block, bfq: fix waker_bfqq UAF after bfq_split_bfqq() 2025-01-17 13:40:59 +01:00
bfq-iosched.h
bfq-wf2q.c
bio-integrity.c block: integrity: Do not call set_page_dirty_lock() 2025-04-25 10:47:50 +02:00
bio.c scsi: sd_zbc: block: Respect bio vector limits for REPORT ZONES buffer 2025-05-22 14:29:49 +02:00
blk-cgroup-fc-appid.c
blk-cgroup-rwstat.c
blk-cgroup-rwstat.h
blk-cgroup.c blk-cgroup: Fix class @block_class's subsystem refcount leakage 2025-02-17 10:05:12 +01:00
blk-cgroup.h
blk-core.c block: add a rq_list type 2025-04-25 10:48:06 +02:00
blk-crypto-fallback.c
blk-crypto-internal.h
blk-crypto-profile.c
blk-crypto-sysfs.c
blk-crypto.c
blk-flush.c
blk-ia-ranges.c
blk-integrity.c
blk-ioc.c
blk-iocost.c
blk-iolatency.c
blk-ioprio.c
blk-ioprio.h
blk-lib.c
blk-map.c
blk-merge.c block: remove the ioprio field from struct request 2025-05-02 07:58:54 +02:00
blk-mq-cpumap.c blk-mq: create correct map for fallback case 2025-05-09 09:50:48 +02:00
blk-mq-debugfs.c
blk-mq-debugfs.h
blk-mq-pci.c
blk-mq-sched.c
blk-mq-sched.h
blk-mq-sysfs.c
blk-mq-tag.c
blk-mq-virtio.c
blk-mq.c block: make sure ->nr_integrity_segments is cloned in blk_rq_prep_clone 2025-05-02 07:58:54 +02:00
blk-mq.h block: add a rq_list type 2025-04-25 10:48:06 +02:00
blk-pm.c
blk-pm.h
blk-rq-qos.c
blk-rq-qos.h
blk-settings.c block: never reduce ra_pages in blk_apply_bdi_limits 2025-05-02 07:59:03 +02:00
blk-stat.c
blk-stat.h
blk-sysfs.c block: fix resource leak in blk_register_queue() error path 2025-04-25 10:47:43 +02:00
blk-throttle.c
blk-throttle.h
blk-timeout.c
blk-wbt.c
blk-wbt.h
blk-zoned.c block: fix race between set_blocksize and read paths 2025-05-29 11:02:01 +02:00
blk.h
bounce.c
bsg-lib.c
bsg.c
disk-events.c
early-lookup.c
elevator.c
elevator.h
fops.c block: fix race between set_blocksize and read paths 2025-05-29 11:02:01 +02:00
genhd.c block: retry call probe after request_module in blk_request_module 2025-02-08 09:56:51 +01:00
holder.c
ioctl.c block: fix race between set_blocksize and read paths 2025-05-29 11:02:01 +02:00
ioprio.c
Kconfig
Kconfig.iosched
kyber-iosched.c
Makefile
mq-deadline.c mq-deadline: don't call req_get_ioprio from the I/O completion handler 2025-05-02 07:59:33 +02:00
opal_proto.h
sed-opal.c
t10-pi.c