From f7ce2f7915834dd3a2c8c3845a5a9962eb93643f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 6 Sep 2022 14:04:01 +0200 Subject: [PATCH] 5.4-stable patches added patches: btrfs-harden-identification-of-a-stale-device.patch --- ...den-identification-of-a-stale-device.patch | 95 +++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 96 insertions(+) create mode 100644 queue-5.4/btrfs-harden-identification-of-a-stale-device.patch diff --git a/queue-5.4/btrfs-harden-identification-of-a-stale-device.patch b/queue-5.4/btrfs-harden-identification-of-a-stale-device.patch new file mode 100644 index 00000000000..f854cdc4798 --- /dev/null +++ b/queue-5.4/btrfs-harden-identification-of-a-stale-device.patch @@ -0,0 +1,95 @@ +From 770c79fb65506fc7c16459855c3839429f46cb32 Mon Sep 17 00:00:00 2001 +From: Anand Jain +Date: Wed, 12 Jan 2022 13:05:59 +0800 +Subject: btrfs: harden identification of a stale device + +From: Anand Jain + +commit 770c79fb65506fc7c16459855c3839429f46cb32 upstream. + +Identifying and removing the stale device from the fs_uuids list is done +by btrfs_free_stale_devices(). btrfs_free_stale_devices() in turn +depends on device_path_matched() to check if the device appears in more +than one btrfs_device structure. + +The matching of the device happens by its path, the device path. However, +when device mapper is in use, the dm device paths are nothing but a link +to the actual block device, which leads to the device_path_matched() +failing to match. + +Fix this by matching the dev_t as provided by lookup_bdev() instead of +plain string compare of the device paths. + +Reported-by: Josef Bacik +Signed-off-by: Anand Jain +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/volumes.c | 44 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 37 insertions(+), 7 deletions(-) + +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -713,15 +713,47 @@ static void pending_bios_fn(struct btrfs + run_scheduled_bios(device); + } + +-static bool device_path_matched(const char *path, struct btrfs_device *device) ++/* ++ * Check if the device in the path matches the device in the given struct device. ++ * ++ * Returns: ++ * true If it is the same device. ++ * false If it is not the same device or on error. ++ */ ++static bool device_matched(const struct btrfs_device *device, const char *path) + { +- int found; ++ char *device_name; ++ struct block_device *bdev_old; ++ struct block_device *bdev_new; ++ ++ /* ++ * If we are looking for a device with the matching dev_t, then skip ++ * device without a name (a missing device). ++ */ ++ if (!device->name) ++ return false; ++ ++ device_name = kzalloc(BTRFS_PATH_NAME_MAX, GFP_KERNEL); ++ if (!device_name) ++ return false; + + rcu_read_lock(); +- found = strcmp(rcu_str_deref(device->name), path); ++ scnprintf(device_name, BTRFS_PATH_NAME_MAX, "%s", rcu_str_deref(device->name)); + rcu_read_unlock(); + +- return found == 0; ++ bdev_old = lookup_bdev(device_name); ++ kfree(device_name); ++ if (IS_ERR(bdev_old)) ++ return false; ++ ++ bdev_new = lookup_bdev(path); ++ if (IS_ERR(bdev_new)) ++ return false; ++ ++ if (bdev_old == bdev_new) ++ return true; ++ ++ return false; + } + + /* +@@ -754,9 +786,7 @@ static int btrfs_free_stale_devices(cons + &fs_devices->devices, dev_list) { + if (skip_device && skip_device == device) + continue; +- if (path && !device->name) +- continue; +- if (path && !device_path_matched(path, device)) ++ if (path && !device_matched(device, path)) + continue; + if (fs_devices->opened) { + /* for an already deleted device return 0 */ diff --git a/queue-5.4/series b/queue-5.4/series index b902bccd171..4eef5c29eb2 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -53,3 +53,4 @@ net-mac802154-fix-a-condition-in-the-receive-path.patch alsa-seq-oss-fix-data-race-for-max_midi_devs-access.patch alsa-seq-fix-data-race-at-module-auto-loading.patch drm-i915-glk-ecs-liva-q2-needs-glk-hdmi-port-timing-quirk.patch +btrfs-harden-identification-of-a-stale-device.patch -- 2.47.3