Skip to content

Commit

Permalink
Revert "btrfs: canonicalize the device path before adding it"
Browse files Browse the repository at this point in the history
This reverts commit 7e06de7.

Commit 7e06de7 ("btrfs: canonicalize the device path before adding
it") tries to make btrfs to use "/dev/mapper/*" name first, then any
filename inside "/dev/" as the device path.

This is mostly fine when there is only the root namespace involved, but
when multiple namespace are involved, things can easily go wrong for the
d_path() usage.

As d_path() returns a file path that is namespace dependent, the
resulted string may not make any sense in another namespace.

Furthermore, the "/dev/" prefix checks itself is not reliable, one can
still make a valid initramfs without devtmpfs, and fill all needed
device nodes manually.

Overall the userspace has all its might to pass whatever device path for
mount, and we are not going to win the war trying to cover every corner
case.

So just revert that commit, and do no extra d_path() based file path
sanity check.

CC: stable@vger.kernel.org # 6.12+
Link: https://lore.kernel.org/linux-fsdevel/20250115185608.GA2223535@zen.localdomain/
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Qu Wenruo authored and David Sterba committed May 2, 2025
1 parent f95d186 commit 8fb1dcb
Showing 1 changed file with 1 addition and 90 deletions.
91 changes: 1 addition & 90 deletions fs/btrfs/volumes.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,82 +733,6 @@ const u8 *btrfs_sb_fsid_ptr(const struct btrfs_super_block *sb)
return has_metadata_uuid ? sb->metadata_uuid : sb->fsid;
}

/*
* We can have very weird soft links passed in.
* One example is "/proc/self/fd/<fd>", which can be a soft link to
* a block device.
*
* But it's never a good idea to use those weird names.
* Here we check if the path (not following symlinks) is a good one inside
* "/dev/".
*/
static bool is_good_dev_path(const char *dev_path)
{
struct path path = { .mnt = NULL, .dentry = NULL };
char *path_buf = NULL;
char *resolved_path;
bool is_good = false;
int ret;

if (!dev_path)
goto out;

path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf)
goto out;

/*
* Do not follow soft link, just check if the original path is inside
* "/dev/".
*/
ret = kern_path(dev_path, 0, &path);
if (ret)
goto out;
resolved_path = d_path(&path, path_buf, PATH_MAX);
if (IS_ERR(resolved_path))
goto out;
if (strncmp(resolved_path, "/dev/", strlen("/dev/")))
goto out;
is_good = true;
out:
kfree(path_buf);
path_put(&path);
return is_good;
}

static int get_canonical_dev_path(const char *dev_path, char *canonical)
{
struct path path = { .mnt = NULL, .dentry = NULL };
char *path_buf = NULL;
char *resolved_path;
int ret;

if (!dev_path) {
ret = -EINVAL;
goto out;
}

path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf) {
ret = -ENOMEM;
goto out;
}

ret = kern_path(dev_path, LOOKUP_FOLLOW, &path);
if (ret)
goto out;
resolved_path = d_path(&path, path_buf, PATH_MAX);
if (IS_ERR(resolved_path)) {
ret = PTR_ERR(resolved_path);
goto out;
}
ret = strscpy(canonical, resolved_path, PATH_MAX);
out:
kfree(path_buf);
path_put(&path);
return ret;
}

static bool is_same_device(struct btrfs_device *device, const char *new_path)
{
struct path old = { .mnt = NULL, .dentry = NULL };
Expand Down Expand Up @@ -1513,23 +1437,12 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
bool new_device_added = false;
struct btrfs_device *device = NULL;
struct file *bdev_file;
char *canonical_path = NULL;
u64 bytenr;
dev_t devt;
int ret;

lockdep_assert_held(&uuid_mutex);

if (!is_good_dev_path(path)) {
canonical_path = kmalloc(PATH_MAX, GFP_KERNEL);
if (canonical_path) {
ret = get_canonical_dev_path(path, canonical_path);
if (ret < 0) {
kfree(canonical_path);
canonical_path = NULL;
}
}
}
/*
* Avoid an exclusive open here, as the systemd-udev may initiate the
* device scan which may race with the user's mount or mkfs command,
Expand Down Expand Up @@ -1574,8 +1487,7 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
goto free_disk_super;
}

device = device_list_add(canonical_path ? : path, disk_super,
&new_device_added);
device = device_list_add(path, disk_super, &new_device_added);
if (!IS_ERR(device) && new_device_added)
btrfs_free_stale_devices(device->devt, device);

Expand All @@ -1584,7 +1496,6 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,

error_bdev_put:
fput(bdev_file);
kfree(canonical_path);

return device;
}
Expand Down

0 comments on commit 8fb1dcb

Please sign in to comment.