public inbox for linux-block@vger.kernel.org
 help / color / mirror / Atom feed
* [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