On 3/19/20 2:44 PM, Goffredo Baroncelli wrote:
Hi Josef,
On 3/19/20 7:15 PM, Josef Bacik wrote:
On 3/19/20 2:05 PM, Goffredo Baroncelli wrote:
From: Goffredo Baroncelli <kreijack@xxxxxxxxx>
Add a new ioctl to get info about chunk without requiring the root privileges.
This allow to a non root user to know how the space of the filesystem is
allocated.
Signed-off-by: Goffredo Baroncelli <kreijack@xxxxxxxxx>
---
fs/btrfs/ioctl.c | 211 +++++++++++++++++++++++++++++++++++++
include/uapi/linux/btrfs.h | 38 +++++++
2 files changed, 249 insertions(+)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 40b729dce91c..e9231d597422 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2234,6 +2234,215 @@ static noinline int btrfs_ioctl_tree_search_v2(struct
file *file,
return ret;
}
+/*
+ * Return:
+ * 0 -> copied all data, possible further data
+ * 1 -> copied all data, no further data
+ * -EAGAIN -> not enough space, restart it
+ * -EFAULT -> the user passed an invalid address/size pair
+ */
+static noinline int copy_chunk_info(struct btrfs_path *path,
+ char __user *ubuf,
+ size_t buf_size,
+ u64 *used_buf,
+ int *num_found,
+ u64 *offset)
+{
+ struct extent_buffer *leaf;
+ unsigned long item_off;
+ unsigned long item_len;
+ int nritems;
+ int i;
+ int slot;
+ struct btrfs_key key;
+
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+ nritems = btrfs_header_nritems(leaf);
+
+ for (i = slot; i < nritems; i++) {
+ u64 destsize;
+ struct btrfs_chunk_info ci;
+ struct btrfs_chunk chunk;
+ int j, chunk_size;
+
+ item_off = btrfs_item_ptr_offset(leaf, i);
+ item_len = btrfs_item_size_nr(leaf, i);
+
+ btrfs_item_key_to_cpu(leaf, &key, i);
+ /*
+ * we are not interested in other items type
+ */
+ if (key.type != BTRFS_CHUNK_ITEM_KEY)
+ return 1;
+
We'll leak this to user space, this should probably be handled differently
right? Thanks,
Likely I am missing something obvious, but I can't understand what can be leaked
and why. Could you be so kindly to elaborate your answer ?
Many thanks
we return 1 here
+ ret = copy_chunk_info(path, ubuf, buf_size,
+ &used_buf, items_count, offset);
+
+ btrfs_release_path(path);
+ if (ret)
+ break;
this bit breaks and we return ret
+ ret = search_chunk_info(inode, &arg.offset, &arg.items_count,
+ argp + data_offset, buf_size - data_offset);
+
+ if (copy_to_user(argp, &arg, data_offset))
+ return -EFAULT;
+
+ return ret;
and we return ret here. So we'd return 1 to userspace. Thanks,
Josef