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, &params, sizeof(params)))
-               return -EFAULT;
-
+       memcpy(arg, &params, 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(&params, arg, sizeof(params)))
-               return -EFAULT;
+       memcpy(&params, 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, &params, sizeof(params)))
-               return -EFAULT;
-
+       memcpy(arg, &params, 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, &params, sizeof(params)))
-                       return -EFAULT;
-       }
+       if (ret == 0)
+               memcpy(arg, &params, 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

Reply via email to