diff options
author | Omar Sandoval <osandov@fb.com> | 2018-11-13 23:47:02 -0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-11-26 16:45:30 +0100 |
commit | bfe2dc379662bd2aba40db9fe9185a57dae0c4a9 (patch) | |
tree | 1e59cac3e50c9f14d503713bc84317091772e040 /libbtrfsutil/subvolume.c | |
parent | 39ac43a2a47cf99cb4914696b51f8d9e28abd0d9 (diff) |
libbtrfsutil: relax the privileges of subvolume_info()
Attempt to use the BTRFS_IOC_GET_SUBVOL_INFO ioctl (added in kernel
4.18) for subvolume_info() if not root. Also, rename
get_subvolume_info_root() -> get_subvolume_info_privileged() for
consistency with further changes.
This is based on a patch from Misono Tomohiro.
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'libbtrfsutil/subvolume.c')
-rw-r--r-- | libbtrfsutil/subvolume.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/libbtrfsutil/subvolume.c b/libbtrfsutil/subvolume.c index 0d7ef5bf..69654db4 100644 --- a/libbtrfsutil/subvolume.c +++ b/libbtrfsutil/subvolume.c @@ -31,6 +31,11 @@ #include "btrfsutil_internal.h" +static bool is_root(void) +{ + return geteuid() == 0; +} + /* * This intentionally duplicates btrfs_util_is_subvolume_fd() instead of opening * a file descriptor and calling it, because fstat() and fstatfs() don't accept @@ -295,8 +300,8 @@ PUBLIC enum btrfs_util_error btrfs_util_subvolume_info(const char *path, return err; } -static enum btrfs_util_error get_subvolume_info_root(int fd, uint64_t id, - struct btrfs_util_subvolume_info *subvol) +static enum btrfs_util_error get_subvolume_info_privileged(int fd, uint64_t id, + struct btrfs_util_subvolume_info *subvol) { struct btrfs_ioctl_search_args search = { .key = { @@ -383,6 +388,45 @@ static enum btrfs_util_error get_subvolume_info_root(int fd, uint64_t id, return BTRFS_UTIL_OK; } +static enum btrfs_util_error get_subvolume_info_unprivileged(int fd, + struct btrfs_util_subvolume_info *subvol) +{ + struct btrfs_ioctl_get_subvol_info_args info; + int ret; + + ret = ioctl(fd, BTRFS_IOC_GET_SUBVOL_INFO, &info); + if (ret == -1) + return BTRFS_UTIL_ERROR_GET_SUBVOL_INFO_FAILED; + + subvol->id = info.treeid; + subvol->parent_id = info.parent_id; + subvol->dir_id = info.dirid; + subvol->flags = info.flags; + subvol->generation = info.generation; + + memcpy(subvol->uuid, info.uuid, sizeof(subvol->uuid)); + memcpy(subvol->parent_uuid, info.parent_uuid, + sizeof(subvol->parent_uuid)); + memcpy(subvol->received_uuid, info.received_uuid, + sizeof(subvol->received_uuid)); + + subvol->ctransid = info.ctransid; + subvol->otransid = info.otransid; + subvol->stransid = info.stransid; + subvol->rtransid = info.rtransid; + + subvol->ctime.tv_sec = info.ctime.sec; + subvol->ctime.tv_nsec = info.ctime.nsec; + subvol->otime.tv_sec = info.otime.sec; + subvol->otime.tv_nsec = info.otime.nsec; + subvol->stime.tv_sec = info.stime.sec; + subvol->stime.tv_nsec = info.stime.nsec; + subvol->rtime.tv_sec = info.rtime.sec; + subvol->rtime.tv_nsec = info.rtime.nsec; + + return BTRFS_UTIL_OK; +} + PUBLIC enum btrfs_util_error btrfs_util_subvolume_info_fd(int fd, uint64_t id, struct btrfs_util_subvolume_info *subvol) { @@ -393,6 +437,9 @@ PUBLIC enum btrfs_util_error btrfs_util_subvolume_info_fd(int fd, uint64_t id, if (err) return err; + if (!is_root()) + return get_subvolume_info_unprivileged(fd, subvol); + err = btrfs_util_subvolume_id_fd(fd, &id); if (err) return err; @@ -404,7 +451,7 @@ PUBLIC enum btrfs_util_error btrfs_util_subvolume_info_fd(int fd, uint64_t id, return BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND; } - return get_subvolume_info_root(fd, id, subvol); + return get_subvolume_info_privileged(fd, id, subvol); } PUBLIC enum btrfs_util_error btrfs_util_get_subvolume_read_only_fd(int fd, |