Skip to content

Commit 3ff56e2

Browse files
committed
block: count BLK_OPEN_RESTRICT_WRITES openers
The original changes in v6.8 do allow for a block device to be reopened with BLK_OPEN_RESTRICT_WRITES provided the same holder is used as per bdev_may_open(). I think this has a bug. The first opener @F1 of that block device will set bdev->bd_writers to -1. The second opener @F2 using the same holder will pass the check in bdev_may_open() that bdev->bd_writers must not be greater than zero. The first opener @F1 now closes the block device and in bdev_release() will end up calling bdev_yield_write_access() which calls bdev_writes_blocked() and sets bdev->bd_writers to 0 again. Now @F2 holds a file to that block device which was opened with exclusive write access but bdev->bd_writers has been reset to 0. So now @f3 comes along and succeeds in opening the block device with BLK_OPEN_WRITE betraying @F2's request to have exclusive write access. This isn't a practical issue yet because afaict there's no codepath inside the kernel that reopenes the same block device with BLK_OPEN_RESTRICT_WRITES but it will be if there is. Fix this by counting the number of BLK_OPEN_RESTRICT_WRITES openers. So we only allow writes again once all BLK_OPEN_RESTRICT_WRITES openers are done. Link: https://lore.kernel.org/r/20240323-abtauchen-klauen-c2953810082d@brauner Fixes: ed5cc70 ("block: Add config option to not allow writing to mounted devices") Reviewed-by: Jan Kara <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent ddd65e1 commit 3ff56e2

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

block/bdev.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -776,17 +776,17 @@ void blkdev_put_no_open(struct block_device *bdev)
776776

777777
static bool bdev_writes_blocked(struct block_device *bdev)
778778
{
779-
return bdev->bd_writers == -1;
779+
return bdev->bd_writers < 0;
780780
}
781781

782782
static void bdev_block_writes(struct block_device *bdev)
783783
{
784-
bdev->bd_writers = -1;
784+
bdev->bd_writers--;
785785
}
786786

787787
static void bdev_unblock_writes(struct block_device *bdev)
788788
{
789-
bdev->bd_writers = 0;
789+
bdev->bd_writers++;
790790
}
791791

792792
static bool bdev_may_open(struct block_device *bdev, blk_mode_t mode)

0 commit comments

Comments
 (0)