Implement ->proc_ioctl_buf() so procfs copies the arguments in before it pins the entry and back out after unpinning it. The commands encode their arguments. procfs converts the pointers of 32-bit tasks, so allocinfo_compat_ioctl() goes away.
Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- mm/alloc_tag.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c index 788c9d7f7151..1734705e2990 100644 --- a/mm/alloc_tag.c +++ b/mm/alloc_tag.c @@ -6,7 +6,6 @@ #include <linux/kallsyms.h> #include <linux/module.h> #include <linux/mutex.h> -#include <linux/compat.h> #include <linux/page_ext.h> #include <linux/pgalloc_tag.h> #include <linux/proc_fs.h> @@ -235,16 +234,14 @@ static void allocinfo_to_params(struct codetag *ct, * Retrieves the unique content ID representing the current allocation tag module * layout, allowing userspace to detect if modules were loaded / unloaded. */ -static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg) +static int allocinfo_ioctl_get_content_id(struct seq_file *m, void *arg) { struct allocinfo_content_id params; codetag_lock_module_list(alloc_tag_cttype); params.id = codetag_get_content_id(alloc_tag_cttype); codetag_unlock_module_list(alloc_tag_cttype); - if (copy_to_user(arg, ¶ms, sizeof(params))) - return -EFAULT; - + memcpy(arg, ¶ms, sizeof(params)); return 0; } @@ -309,7 +306,7 @@ static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter, * Seeks the ioctl iterator to the specified 0-indexed tag position, reads its * profiling data and returns it to userspace. */ -static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg) +static int allocinfo_ioctl_get_at(struct seq_file *m, void *arg) { struct allocinfo_private *priv; struct codetag *ct; @@ -318,8 +315,7 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg) struct alloc_tag_counters counters; bool fetched_counters; - if (copy_from_user(¶ms, arg, sizeof(params))) - return -EFAULT; + memcpy(¶ms, arg, sizeof(params)); if (params.filter.mask & ~ALLOCINFO_FILTER_MASKS) return -EINVAL; @@ -374,9 +370,7 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg) if (!ct) return -ENOENT; - if (copy_to_user(arg, ¶ms, sizeof(params))) - return -EFAULT; - + memcpy(arg, ¶ms, sizeof(params)); return 0; } @@ -384,7 +378,7 @@ static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg) * Advances the ioctl iterator to the next allocation tag in the sequence and * returns its profiling data to userspace. */ -static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg) +static int allocinfo_ioctl_get_next(struct seq_file *m, void *arg) { struct allocinfo_private *priv; struct codetag *ct; @@ -424,10 +418,8 @@ static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg) codetag_unlock_module_list(alloc_tag_cttype); mutex_unlock(&priv->ioctl_lock); - if (ret == 0) { - if (copy_to_user(arg, ¶ms, sizeof(params))) - return -EFAULT; - } + if (ret == 0) + memcpy(arg, ¶ms, sizeof(params)); return ret; } @@ -435,10 +427,8 @@ static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg) * Entry point ioctl function for /proc/allocinfo routing requests to fetch the * layout content ID, seek to a specific tag, or read sequential tags. */ -static long allocinfo_ioctl(struct file *file, unsigned int cmd, - unsigned long __arg) +static long allocinfo_ioctl(struct file *file, unsigned int cmd, void *arg) { - void __user *arg = (void __user *)__arg; int ret; switch (cmd) { @@ -459,23 +449,20 @@ static long allocinfo_ioctl(struct file *file, unsigned int cmd, return ret; } -#ifdef CONFIG_COMPAT -static long allocinfo_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - return allocinfo_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); -} -#endif +static const struct proc_ioctl_arg allocinfo_ioctl_args[] = { + PROC_IOCTL_IOC(ALLOCINFO_IOC_CONTENT_ID), + PROC_IOCTL_IOC(ALLOCINFO_IOC_GET_AT), + PROC_IOCTL_IOC(ALLOCINFO_IOC_GET_NEXT), +}; static const struct proc_ops allocinfo_proc_ops = { .proc_seq_ops = &allocinfo_seq_op, .proc_state_size = sizeof(struct allocinfo_private), .proc_open = allocinfo_open, .proc_release = allocinfo_release, - .proc_ioctl = allocinfo_ioctl, -#ifdef CONFIG_COMPAT - .proc_compat_ioctl = allocinfo_compat_ioctl, -#endif + .proc_ioctl_buf = allocinfo_ioctl, + .proc_ioctl_args = allocinfo_ioctl_args, + .proc_nr_ioctl_args = ARRAY_SIZE(allocinfo_ioctl_args), }; size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep) -- 2.53.0
