kernel/*: switch to memdup_user_nul()
[cascardo/linux.git] / kernel / user_namespace.c
index 88fefa6..9bafc21 100644 (file)
@@ -602,8 +602,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        struct uid_gid_map new_map;
        unsigned idx;
        struct uid_gid_extent *extent = NULL;
-       unsigned long page = 0;
-       char *kbuf, *pos, *next_line;
+       char *kbuf = NULL, *pos, *next_line;
        ssize_t ret = -EINVAL;
 
        /*
@@ -638,23 +637,18 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
                goto out;
 
-       /* Get a buffer */
-       ret = -ENOMEM;
-       page = __get_free_page(GFP_TEMPORARY);
-       kbuf = (char *) page;
-       if (!page)
-               goto out;
-
        /* Only allow < page size writes at the beginning of the file */
        ret = -EINVAL;
        if ((*ppos != 0) || (count >= PAGE_SIZE))
                goto out;
 
        /* Slurp in the user data */
-       ret = -EFAULT;
-       if (copy_from_user(kbuf, buf, count))
+       kbuf = memdup_user_nul(buf, count);
+       if (IS_ERR(kbuf)) {
+               ret = PTR_ERR(kbuf);
+               kbuf = NULL;
                goto out;
-       kbuf[count] = '\0';
+       }
 
        /* Parse the user data */
        ret = -EINVAL;
@@ -756,8 +750,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
        ret = count;
 out:
        mutex_unlock(&userns_state_mutex);
-       if (page)
-               free_page(page);
+       kfree(kbuf);
        return ret;
 }