diff options
Diffstat (limited to 'kernel/user_namespace.c')
| -rw-r--r-- | kernel/user_namespace.c | 21 | 
1 files changed, 7 insertions, 14 deletions
| diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 88fefa68c516..9bafc211930c 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -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;  } | 
