Commit 01b810b8 authored by David Sterba's avatar David Sterba Committed by Chris Mason

btrfs: make root id query unprivileged

The INO_LOOKUP ioctl can lookup path for a given inode number and is
thus restricted. As a sideefect it can find the root id of the
containing subvolume and we're using this int the 'btrfs inspect rootid'
command.

The restriction is unnecessary in case we set the ioctl args
 args::treeid    = 0
 args::objectid  = 256 (BTRFS_FIRST_FREE_OBJECTID)

Then the path will be empty and the treeid is filled with the root id of
the inode on which the ioctl is called. This behaviour is unchanged,
after the root restriction is removed.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.cz>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 2e6e5183
...@@ -2271,10 +2271,7 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, ...@@ -2271,10 +2271,7 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file,
{ {
struct btrfs_ioctl_ino_lookup_args *args; struct btrfs_ioctl_ino_lookup_args *args;
struct inode *inode; struct inode *inode;
int ret; int ret = 0;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
args = memdup_user(argp, sizeof(*args)); args = memdup_user(argp, sizeof(*args));
if (IS_ERR(args)) if (IS_ERR(args))
...@@ -2282,13 +2279,28 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, ...@@ -2282,13 +2279,28 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file,
inode = file_inode(file); inode = file_inode(file);
/*
* Unprivileged query to obtain the containing subvolume root id. The
* path is reset so it's consistent with btrfs_search_path_in_tree.
*/
if (args->treeid == 0) if (args->treeid == 0)
args->treeid = BTRFS_I(inode)->root->root_key.objectid; args->treeid = BTRFS_I(inode)->root->root_key.objectid;
if (args->objectid == BTRFS_FIRST_FREE_OBJECTID) {
args->name[0] = 0;
goto out;
}
if (!capable(CAP_SYS_ADMIN)) {
ret = -EPERM;
goto out;
}
ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info, ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info,
args->treeid, args->objectid, args->treeid, args->objectid,
args->name); args->name);
out:
if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) if (ret == 0 && copy_to_user(argp, args, sizeof(*args)))
ret = -EFAULT; ret = -EFAULT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment