* [PATCH] loop: block loop reconfiguration of offset/sizelimit on mounted device
@ 2026-03-30 4:43 Deepanshu Kartikey
2026-03-30 5:54 ` Christoph Hellwig
0 siblings, 1 reply; 2+ messages in thread
From: Deepanshu Kartikey @ 2026-03-30 4:43 UTC (permalink / raw)
To: axboe, tytso, dvyukov
Cc: adilger.kernel, linux-block, linux-kernel, linux-ext4,
Deepanshu Kartikey, syzbot+fb32afec111a7d61b939
LOOP_SET_STATUS{64} allows changing lo_offset and lo_sizelimit while
a filesystem is mounted on the loop device. This effectively mutates
the data visible to the mounted filesystem, which is equivalent to
writing directly to the block device.
When bdev_allow_write_mounted is false, direct writes to a mounted
block device are blocked via bdev_writes_blocked(). However,
LOOP_SET_STATUS{64} bypasses this protection because it modifies
the loop configuration through an ioctl rather than opening the
block device for writing.
Fix this by checking bdev_writes_blocked() before allowing changes
to lo_offset or lo_sizelimit. If the loop device has writes blocked
(indicating a filesystem is mounted with write protection), return
-EBUSY. Other loop status fields that do not affect the visible
data can still be changed while mounted.
Export bdev_writes_blocked() so it can be used from the loop driver.
Suggested-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=fb32afec111a7d61b939
Tested-by: syzbot+fb32afec111a7d61b939@syzkaller.appspotmail.com
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
block/bdev.c | 4 +++-
drivers/block/loop.c | 12 ++++++++++++
include/linux/blkdev.h | 1 +
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/block/bdev.c b/block/bdev.c
index ed022f8c48c7..96520fac7b2f 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -860,10 +860,12 @@ void blkdev_put_no_open(struct block_device *bdev)
put_device(&bdev->bd_device);
}
-static bool bdev_writes_blocked(struct block_device *bdev)
+bool bdev_writes_blocked(struct block_device *bdev)
{
return bdev->bd_writers < 0;
}
+EXPORT_SYMBOL_GPL(bdev_writes_blocked);
+
static void bdev_block_writes(struct block_device *bdev)
{
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0000913f7efc..3f3a29abad1f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1239,6 +1239,18 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
goto out_unlock;
}
+ /*
+ * Changing lo_offset or lo_sizelimit on a mounted device is
+ * equivalent to modifying the block device contents, block
+ * this if writes are blocked on the device.
+ */
+ if ((lo->lo_offset != info->lo_offset ||
+ lo->lo_sizelimit != info->lo_sizelimit) &&
+ bdev_writes_blocked(lo->lo_device)) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+
if (lo->lo_offset != info->lo_offset ||
lo->lo_sizelimit != info->lo_sizelimit) {
size_changed = true;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index d463b9b5a0a5..6b908e9dd035 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -820,6 +820,7 @@ static inline bool bdev_read_only(struct block_device *bdev)
return bdev_test_flag(bdev, BD_READ_ONLY) || get_disk_ro(bdev->bd_disk);
}
+bool bdev_writes_blocked(struct block_device *bdev);
bool set_capacity_and_notify(struct gendisk *disk, sector_t size);
void disk_force_media_change(struct gendisk *disk);
void bdev_mark_dead(struct block_device *bdev, bool surprise);
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] loop: block loop reconfiguration of offset/sizelimit on mounted device
2026-03-30 4:43 [PATCH] loop: block loop reconfiguration of offset/sizelimit on mounted device Deepanshu Kartikey
@ 2026-03-30 5:54 ` Christoph Hellwig
0 siblings, 0 replies; 2+ messages in thread
From: Christoph Hellwig @ 2026-03-30 5:54 UTC (permalink / raw)
To: Deepanshu Kartikey
Cc: axboe, tytso, dvyukov, adilger.kernel, linux-block, linux-kernel,
linux-ext4, syzbot+fb32afec111a7d61b939
On Mon, Mar 30, 2026 at 10:13:34AM +0530, Deepanshu Kartikey wrote:
> LOOP_SET_STATUS{64} allows changing lo_offset and lo_sizelimit while
> a filesystem is mounted on the loop device. This effectively mutates
> the data visible to the mounted filesystem, which is equivalent to
> writing directly to the block device.
Increasing the size certainly does not do that.
> Export bdev_writes_blocked() so it can be used from the loop driver.
I'm not sure exporting this is a good idea. Besides the growing the
device part above, if someone insist on changing the size, they could
do this just fine with a remove block device, so prohibiting it locally
just because we can seems odd. And exporting a helper with obscure
usage for a strange use case without documenting that is rarely a
good idea.
> -static bool bdev_writes_blocked(struct block_device *bdev)
> +bool bdev_writes_blocked(struct block_device *bdev)
> {
> return bdev->bd_writers < 0;
> }
> +EXPORT_SYMBOL_GPL(bdev_writes_blocked);
> +
>
> static void bdev_block_writes(struct block_device *bdev)
... and if we were to make it public it should be inline, and in a
separate patch.
And if not this would still add a spurious empty line.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-03-30 5:54 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-30 4:43 [PATCH] loop: block loop reconfiguration of offset/sizelimit on mounted device Deepanshu Kartikey
2026-03-30 5:54 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox