proc_pid_attr_write(): switch to memdup_user()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 24 Dec 2015 05:16:30 +0000 (00:16 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 4 Jan 2016 15:28:00 +0000 (10:28 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/proc/base.c

index 4bd5d3118acd4b152d6e6f17b38b0a03b0f723d6..1b0f470a3e35cff35ef6383621af5ef166012db9 100644 (file)
@@ -2359,7 +2359,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
                                   size_t count, loff_t *ppos)
 {
        struct inode * inode = file_inode(file);
-       char *page;
+       void *page;
        ssize_t length;
        struct task_struct *task = get_proc_task(inode);
 
@@ -2374,14 +2374,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
        if (*ppos != 0)
                goto out;
 
-       length = -ENOMEM;
-       page = (char*)__get_free_page(GFP_TEMPORARY);
-       if (!page)
+       page = memdup_user(buf, count);
+       if (IS_ERR(page)) {
+               length = PTR_ERR(page);
                goto out;
-
-       length = -EFAULT;
-       if (copy_from_user(page, buf, count))
-               goto out_free;
+       }
 
        /* Guard against adverse ptrace interaction */
        length = mutex_lock_interruptible(&task->signal->cred_guard_mutex);
@@ -2390,10 +2387,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
 
        length = security_setprocattr(task,
                                      (char*)file->f_path.dentry->d_name.name,
-                                     (void*)page, count);
+                                     page, count);
        mutex_unlock(&task->signal->cred_guard_mutex);
 out_free:
-       free_page((unsigned long) page);
+       kfree(page);
 out:
        put_task_struct(task);
 out_no_task: