new primitive: vmemdup_user()
similar to memdup_user(), but does *not* guarantee that result will be physically contiguous; use only in cases where that's not a requirement and free it with kvfree(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									6c2c97a24f
								
							
						
					
					
						commit
						50fd2f298b
					
				| @ -11,6 +11,7 @@ | |||||||
| 
 | 
 | ||||||
| extern char *strndup_user(const char __user *, long); | extern char *strndup_user(const char __user *, long); | ||||||
| extern void *memdup_user(const void __user *, size_t); | extern void *memdup_user(const void __user *, size_t); | ||||||
|  | extern void *vmemdup_user(const void __user *, size_t); | ||||||
| extern void *memdup_user_nul(const void __user *, size_t); | extern void *memdup_user_nul(const void __user *, size_t); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								mm/util.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								mm/util.c
									
									
									
									
									
								
							| @ -150,7 +150,8 @@ EXPORT_SYMBOL(kmemdup_nul); | |||||||
|  * @src: source address in user space |  * @src: source address in user space | ||||||
|  * @len: number of bytes to copy |  * @len: number of bytes to copy | ||||||
|  * |  * | ||||||
|  * Returns an ERR_PTR() on failure. |  * Returns an ERR_PTR() on failure.  Result is physically | ||||||
|  |  * contiguous, to be freed by kfree(). | ||||||
|  */ |  */ | ||||||
| void *memdup_user(const void __user *src, size_t len) | void *memdup_user(const void __user *src, size_t len) | ||||||
| { | { | ||||||
| @ -169,6 +170,32 @@ void *memdup_user(const void __user *src, size_t len) | |||||||
| } | } | ||||||
| EXPORT_SYMBOL(memdup_user); | EXPORT_SYMBOL(memdup_user); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * vmemdup_user - duplicate memory region from user space | ||||||
|  |  * | ||||||
|  |  * @src: source address in user space | ||||||
|  |  * @len: number of bytes to copy | ||||||
|  |  * | ||||||
|  |  * Returns an ERR_PTR() on failure.  Result may be not | ||||||
|  |  * physically contiguous.  Use kvfree() to free. | ||||||
|  |  */ | ||||||
|  | void *vmemdup_user(const void __user *src, size_t len) | ||||||
|  | { | ||||||
|  | 	void *p; | ||||||
|  | 
 | ||||||
|  | 	p = kvmalloc(len, GFP_USER); | ||||||
|  | 	if (!p) | ||||||
|  | 		return ERR_PTR(-ENOMEM); | ||||||
|  | 
 | ||||||
|  | 	if (copy_from_user(p, src, len)) { | ||||||
|  | 		kvfree(p); | ||||||
|  | 		return ERR_PTR(-EFAULT); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return p; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(vmemdup_user); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * strndup_user - duplicate an existing string from user space |  * strndup_user - duplicate an existing string from user space | ||||||
|  * @s: The string to duplicate |  * @s: The string to duplicate | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user