linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jan Kara <jack@suse.cz>
To: Jens Axboe <axboe@kernel.dk>
Cc: <linux-block@vger.kernel.org>,
	Christoph Hellwig <hch@infradead.org>,
	Dmitry Vyukov <dvyukov@google.com>, Ted Tso <tytso@mit.edu>,
	yebin <yebin@huaweicloud.com>, <linux-fsdevel@vger.kernel.org>,
	Jan Kara <jack@suse.cz>
Subject: [PATCH] block: Add config option to not allow writing to mounted devices
Date: Mon, 12 Jun 2023 18:16:14 +0200	[thread overview]
Message-ID: <20230612161614.10302-1-jack@suse.cz> (raw)

Writing to mounted devices is dangerous and can lead to filesystem
corruption as well as crashes. Furthermore syzbot comes with more and
more involved examples how to corrupt block device under a mounted
filesystem leading to kernel crashes and reports we can do nothing
about. Add config option to disallow writing to mounted (exclusively
open) block devices. Syzbot can use this option to avoid uninteresting
crashes. Also users whose userspace setup does not need writing to
mounted block devices can set this config option for hardening.

Link: https://lore.kernel.org/all/60788e5d-5c7c-1142-e554-c21d709acfd9@linaro.org
Signed-off-by: Jan Kara <jack@suse.cz>
---
 block/Kconfig             | 12 ++++++++++++
 block/bdev.c              | 10 ++++++++++
 include/linux/blk_types.h |  3 +++
 3 files changed, 25 insertions(+)

FWIW I've tested this and my test VM with ext4 root fs boots fine and fstests
on ext4 seem to be also running fine with BLK_DEV_WRITE_HARDENING enabled.
OTOH my old VM setup which is not using initrd fails to boot with
BLK_DEV_WRITE_HARDENING enabled because fsck cannot open the root device
because the root is already mounted (read-only). Anyway this should be useful
for syzbot (Dmitry indicated interest in this option in the past) and maybe
other well controlled setups.

diff --git a/block/Kconfig b/block/Kconfig
index 86122e459fe0..c44e2238e18d 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -77,6 +77,18 @@ config BLK_DEV_INTEGRITY_T10
 	select CRC_T10DIF
 	select CRC64_ROCKSOFT
 
+config BLK_DEV_WRITE_HARDENING
+	bool "Do not allow writing to mounted devices"
+	help
+	When a block device is mounted, writing to its buffer cache very likely
+	going to cause filesystem corruption. It is also rather easy to crash
+	the kernel in this way since the filesystem has no practical way of
+	detecting these writes to buffer cache and verifying its metadata
+	integrity. Select this option to disallow writing to mounted devices.
+	This should be mostly fine but some filesystems (e.g. ext4) rely on
+	the ability of filesystem tools to write to mounted filesystems to
+	set e.g. UUID or run fsck on the root filesystem in some setups.
+
 config BLK_DEV_ZONED
 	bool "Zoned block device support"
 	select MQ_IOSCHED_DEADLINE
diff --git a/block/bdev.c b/block/bdev.c
index 21c63bfef323..ad01f0a6af0d 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -602,6 +602,12 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode)
 	struct gendisk *disk = bdev->bd_disk;
 	int ret;
 
+	if (IS_ENABLED(BLK_DEV_WRITE_HARDENING)) {
+		if (mode & FMODE_EXCL && atomic_read(&bdev->bd_writers) > 0)
+			return -EBUSY;
+		if (mode & FMODE_WRITE && bdev->bd_holders > 0)
+			return -EBUSY;
+	}
 	if (disk->fops->open) {
 		ret = disk->fops->open(bdev, mode);
 		if (ret) {
@@ -617,6 +623,8 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode)
 		set_init_blocksize(bdev);
 	if (test_bit(GD_NEED_PART_SCAN, &disk->state))
 		bdev_disk_changed(disk, false);
+	if (IS_ENABLED(BLK_DEV_WRITE_HARDENING) && mode & FMODE_WRITE)
+		atomic_inc(&bdev->bd_writers);
 	atomic_inc(&bdev->bd_openers);
 	return 0;
 }
@@ -625,6 +633,8 @@ static void blkdev_put_whole(struct block_device *bdev, fmode_t mode)
 {
 	if (atomic_dec_and_test(&bdev->bd_openers))
 		blkdev_flush_mapping(bdev);
+	if (IS_ENABLED(BLK_DEV_WRITE_HARDENING) && mode & FMODE_WRITE)
+		atomic_dec(&bdev->bd_writers);
 	if (bdev->bd_disk->fops->release)
 		bdev->bd_disk->fops->release(bdev->bd_disk, mode);
 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 740afe80f297..25af3340f316 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -67,6 +67,9 @@ struct block_device {
 	struct partition_meta_info *bd_meta_info;
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	bool			bd_make_it_fail;
+#endif
+#ifdef CONFIG_BLK_DEV_WRITE_HARDENING
+	atomic_t		bd_writers;
 #endif
 	/*
 	 * keep this out-of-line as it's both big and not needed in the fast
-- 
2.35.3


             reply	other threads:[~2023-06-12 16:16 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-12 16:16 Jan Kara [this message]
2023-06-12 16:25 ` [PATCH] block: Add config option to not allow writing to mounted devices Jan Kara
2023-06-12 17:39   ` Bart Van Assche
2023-06-12 17:47     ` Theodore Ts'o
2023-06-12 18:52     ` Colin Walters
2023-06-13 11:34       ` Jan Kara
2023-06-14  1:55         ` Darrick J. Wong
2023-06-14  7:14           ` Christoph Hellwig
2023-06-14  7:05         ` Christian Brauner
2023-06-14  7:07           ` Christoph Hellwig
2023-06-14  7:10         ` Christoph Hellwig
2023-06-14 10:12           ` Jan Kara
2023-06-14 14:30             ` Christoph Hellwig
2023-06-14 14:46             ` Matthew Wilcox
2023-06-13  4:56 ` kernel test robot
2023-06-13  5:10 ` Christoph Hellwig
2023-06-13  6:09   ` Dmitry Vyukov
2023-06-14  7:17     ` Christoph Hellwig
2023-06-14  8:18       ` Christian Brauner
2023-06-14 10:36         ` Jan Kara
2023-06-14 12:48           ` Christian Brauner
2023-06-15 14:39             ` Jan Kara
2023-06-14 14:31         ` Christoph Hellwig
2023-06-13 20:56   ` Jan Kara
2023-06-14  7:20     ` Christoph Hellwig
2023-06-20 10:41       ` Jan Kara
2023-06-20 11:29         ` Christoph Hellwig
2023-06-14  7:35     ` Christian Brauner
2023-06-13  6:49 ` Dmitry Vyukov
2023-06-13 19:22   ` Theodore Ts'o
2023-06-14  0:26   ` Dave Chinner
2023-06-14  2:04   ` Darrick J. Wong
2023-06-14  2:57     ` Theodore Ts'o
2023-06-14 12:27     ` Dmitry Vyukov
2023-06-14 23:38       ` Dave Chinner
2023-06-15  9:14         ` Dmitry Vyukov
2023-06-18 23:35           ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230612161614.10302-1-jack@suse.cz \
    --to=jack@suse.cz \
    --cc=axboe@kernel.dk \
    --cc=dvyukov@google.com \
    --cc=hch@infradead.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=yebin@huaweicloud.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).