summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2024-03-01 08:42:13 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-04-03 15:11:48 +0200
commit5272fe1a77225ac4adfb3c2c87be8215e17be397 (patch)
tree8f988a920a34e5e4c82d5dd27a2c6112fe28349c
parent617d55b90e73c7b4aa2733ca6cc3f9b72d1124bb (diff)
downloadlinux-stable-5272fe1a77225ac4adfb3c2c87be8215e17be397.tar.gz
linux-stable-5272fe1a77225ac4adfb3c2c87be8215e17be397.tar.bz2
linux-stable-5272fe1a77225ac4adfb3c2c87be8215e17be397.zip
btrfs: validate device maj:min during open
commit 9f7eb8405dcbc79c5434821e9e3e92abe187ee8e upstream. Boris managed to create a device capable of changing its maj:min without altering its device path. Only multi-devices can be scanned. A device that gets scanned and remains in the btrfs kernel cache might end up with an incorrect maj:min. Despite the temp-fsid feature patch did not introduce this bug, it could lead to issues if the above multi-device is converted to a single device with a stale maj:min. Subsequently, attempting to mount the same device with the correct maj:min might mistake it for another device with the same fsid, potentially resulting in wrongly auto-enabling the temp-fsid feature. To address this, this patch validates the device's maj:min at the time of device open and updates it if it has changed since the last scan. CC: stable@vger.kernel.org # 6.7+ Fixes: a5b8a5f9f835 ("btrfs: support cloned-device mount capability") Reported-by: Boris Burkov <boris@bur.io> Co-developed-by: Boris Burkov <boris@bur.io> Reviewed-by: Boris Burkov <boris@bur.io># Signed-off-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/btrfs/volumes.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 3b31f558f2dc..fd30dc3d59c8 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -683,6 +683,16 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
device->bdev = bdev_handle->bdev;
clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
+ if (device->devt != device->bdev->bd_dev) {
+ btrfs_warn(NULL,
+ "device %s maj:min changed from %d:%d to %d:%d",
+ device->name->str, MAJOR(device->devt),
+ MINOR(device->devt), MAJOR(device->bdev->bd_dev),
+ MINOR(device->bdev->bd_dev));
+
+ device->devt = device->bdev->bd_dev;
+ }
+
fs_devices->open_devices++;
if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
device->devid != BTRFS_DEV_REPLACE_DEVID) {