Hi,
在 2024/01/09 10:19, Li Lingfeng 写道:
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8S3GW CVE: NA
When writing to a mounted block device is allowed, we need to identify which processes may write to the block device to prevent the file system from being damaged in silence.
Signed-off-by: Li Lingfeng lilingfeng3@huawei.com
block/Kconfig | 9 +++++++++ block/bdev.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/block/Kconfig b/block/Kconfig index 05fdd81a708f..29065fb2860b 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -249,6 +249,15 @@ config BLK_DEV_DETECT_WRITING_PART0 As a supplement to BLK_DEV_WRITE_MOUNTED(_QUIET), enabling this to detect the scenario above.
+config BLK_DEV_WRITE_MOUNTED_QUIET
bool "Keep quiet when detecting conflict of opening block device"
default y
depends on BLK_DEV_WRITE_MOUNTED
help
While writing to mounted block devices is allowed, disabling this
to dump info when opening mounted block devices for write or
trying to mount write opened block devices.
source "block/partitions/Kconfig"
config BLK_MQ_PCI
diff --git a/block/bdev.c b/block/bdev.c index 4b0e6c49a9e7..720b01b4cb45 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -34,10 +34,13 @@ #define BLKDEV_ALLOW_WRITE_MOUNTED 0 /* Should we detect writing to part0 when partitions mounted */ #define BLKDEV_DETECT_WRITING_PART0 1 +/* Should we keep quiet when opening mounted block devices for write? */ +#define BLKDEV_WRITE_MOUNTED_QUIET 2
static u8 bdev_allow_write_mounted = IS_ENABLED(CONFIG_BLK_DEV_WRITE_MOUNTED) << BLKDEV_ALLOW_WRITE_MOUNTED ||
- IS_ENABLED(CONFIG_BLK_DEV_DETECT_WRITING_PART0) << BLKDEV_DETECT_WRITING_PART0;
IS_ENABLED(CONFIG_BLK_DEV_DETECT_WRITING_PART0) << BLKDEV_DETECT_WRITING_PART0 ||
IS_ENABLED(CONFIG_BLK_DEV_WRITE_MOUNTED_QUIET) << BLKDEV_WRITE_MOUNTED_QUIET;
struct bdev_inode { struct block_device bdev;
@@ -739,6 +742,27 @@ void blkdev_put_no_open(struct block_device *bdev) put_device(&bdev->bd_device); }
+static void blkdev_dump_conflict_opener(struct block_device *bdev, char *msg) +{
- char name[BDEVNAME_SIZE];
- struct task_struct *p = NULL;
- char comm_buf[TASK_COMM_LEN];
- pid_t p_pid;
- rcu_read_lock();
- p = rcu_dereference(current->real_parent);
- task_lock(p);
- strncpy(comm_buf, p->comm, TASK_COMM_LEN);
- p_pid = p->pid;
- task_unlock(p);
- rcu_read_unlock();
- snprintf(name, sizeof(name), "%pg", bdev);
- pr_info_ratelimited("%s [%s]. current [%d %s]. parent [%d %s]\n",
msg, name,
current->pid, current->comm, p_pid, comm_buf);
+}
- static bool bdev_writes_blocked(struct block_device *bdev) { return !!bdev->bd_mounters;
@@ -767,10 +791,25 @@ static bool bdev_mount_blocked(struct block_device *bdev) return bdev->bd_writers > 0; }
+static void bdev_dump_info(struct block_device *bdev, blk_mode_t mode) +{
- if (bdev_allow_write_mounted & (1 << BLKDEV_WRITE_MOUNTED_QUIET))
return;
- if (mode & BLK_OPEN_WRITE && bdev_writes_blocked(bdev))
blkdev_dump_conflict_opener(bdev, "VFS: Open an exclusive opened "
"block device for write");
- else if (mode & BLK_OPEN_RESTRICT_WRITES && bdev_mount_blocked(bdev))
blkdev_dump_conflict_opener(bdev, "VFS: Open a write opened "
"block device exclusively");
+}
bdev_dump_info() looks like the same as bdev_may_open(), how about:
bdev_may_open() { bool blocked = false;
if (bdev_allow_write_mounted & (1 << BLKDEV_WRITE_MOUNTED_QUIET)) return true;
if (mode & BLK_OPEN_WRITE && bdev_writes_blocked(bdev)) { blocked = true; bdev_dump... } else is (else if (mode & BLK_OPEN_RESTRICT_WRITES && bdev_mount_blocked(bdev))) { blocked = true; bdev_dump... }
return !blocked || (bdev_allow_write_mounted & (1 << BLKDEV_ALLOW_WRITE_MOUNTED); }
- static bool bdev_may_open(struct block_device *bdev, blk_mode_t mode) {
- if (bdev_allow_write_mounted & (1 << BLKDEV_ALLOW_WRITE_MOUNTED))
- if (bdev_allow_write_mounted & (1 << BLKDEV_ALLOW_WRITE_MOUNTED)) {
return true;bdev_dump_info(bdev, mode);
- } /* Writes blocked? */ if (mode & BLK_OPEN_WRITE && bdev_writes_blocked(bdev)) return false;
@@ -1151,6 +1190,19 @@ static int __init setup_bdev_allow_write_mounted(char *str) if (kstrtou8(str, 0, &bdev_allow_write_mounted)) pr_warn("Invalid option string for bdev_allow_write_mounted:" " '%s'\n", str);
- /*
* It's meaningless to set BLKDEV_WRITE_MOUNTED_QUIET if
* BLKDEV_ALLOW_WRITE_MOUNTED is not set.
*/
- if (!(bdev_allow_write_mounted & (1 << BLKDEV_ALLOW_WRITE_MOUNTED))) {
if (bdev_allow_write_mounted & (1 << BLKDEV_WRITE_MOUNTED_QUIET)) {
pr_warn("Invalid value for bdev_allow_write_mounted:"
" '%d', it should be set as 0/1/2/3/5/7\n",
bdev_allow_write_mounted);
bdev_allow_write_mounted &= ~(1 << BLKDEV_WRITE_MOUNTED_QUIET);
}
- }
- return 1; } __setup("bdev_allow_write_mounted=", setup_bdev_allow_write_mounted);