Commit 35e27a57 authored by Christian Brauner's avatar Christian Brauner

fs: keep struct mnt_id_req extensible

Make it extensible so that we have the liberty to reuse it in future
mount-id based apis. Treat zero size as the first published struct.
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent d8b0f546
...@@ -4956,6 +4956,30 @@ static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq, ...@@ -4956,6 +4956,30 @@ static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq,
return 0; return 0;
} }
static int copy_mnt_id_req(const struct mnt_id_req __user *req,
struct mnt_id_req *kreq)
{
int ret;
size_t usize;
BUILD_BUG_ON(sizeof(struct mnt_id_req) != MNT_ID_REQ_SIZE_VER0);
ret = get_user(usize, &req->size);
if (ret)
return -EFAULT;
if (unlikely(usize > PAGE_SIZE))
return -E2BIG;
if (unlikely(usize < MNT_ID_REQ_SIZE_VER0))
return -EINVAL;
memset(kreq, 0, sizeof(*kreq));
ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize);
if (ret)
return ret;
if (kreq->spare != 0)
return -EINVAL;
return 0;
}
SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
struct statmount __user *, buf, size_t, bufsize, struct statmount __user *, buf, size_t, bufsize,
unsigned int, flags) unsigned int, flags)
...@@ -4970,8 +4994,9 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req, ...@@ -4970,8 +4994,9 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
if (flags) if (flags)
return -EINVAL; return -EINVAL;
if (copy_from_user(&kreq, req, sizeof(kreq))) ret = copy_mnt_id_req(req, &kreq);
return -EFAULT; if (ret)
return ret;
retry: retry:
ret = prepare_kstatmount(&ks, &kreq, buf, bufsize, seq_size); ret = prepare_kstatmount(&ks, &kreq, buf, bufsize, seq_size);
...@@ -5052,8 +5077,9 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, ...@@ -5052,8 +5077,9 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req,
if (flags) if (flags)
return -EINVAL; return -EINVAL;
if (copy_from_user(&kreq, req, sizeof(kreq))) ret = copy_mnt_id_req(req, &kreq);
return -EFAULT; if (ret)
return ret;
mnt_id = kreq.mnt_id; mnt_id = kreq.mnt_id;
last_mnt_id = kreq.param; last_mnt_id = kreq.param;
......
...@@ -184,10 +184,15 @@ struct statmount { ...@@ -184,10 +184,15 @@ struct statmount {
* For listmount(2) @param represents the last listed mount id (or zero). * For listmount(2) @param represents the last listed mount id (or zero).
*/ */
struct mnt_id_req { struct mnt_id_req {
__u32 size;
__u32 spare;
__u64 mnt_id; __u64 mnt_id;
__u64 param; __u64 param;
}; };
/* List of all mnt_id_req versions. */
#define MNT_ID_REQ_SIZE_VER0 24 /* sizeof first published struct */
/* /*
* @mask bits for statmount(2) * @mask bits for statmount(2)
*/ */
......
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