summaryrefslogtreecommitdiffstats
path: root/mm/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/util.c')
-rw-r--r--mm/util.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/mm/util.c b/mm/util.c
index 34e57fae959d..c1250501364f 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -150,18 +150,14 @@ EXPORT_SYMBOL(kmemdup_nul);
150 * @src: source address in user space 150 * @src: source address in user space
151 * @len: number of bytes to copy 151 * @len: number of bytes to copy
152 * 152 *
153 * Returns an ERR_PTR() on failure. 153 * Returns an ERR_PTR() on failure. Result is physically
154 * contiguous, to be freed by kfree().
154 */ 155 */
155void *memdup_user(const void __user *src, size_t len) 156void *memdup_user(const void __user *src, size_t len)
156{ 157{
157 void *p; 158 void *p;
158 159
159 /* 160 p = kmalloc_track_caller(len, GFP_USER);
160 * Always use GFP_KERNEL, since copy_from_user() can sleep and
161 * cause pagefault, which makes it pointless to use GFP_NOFS
162 * or GFP_ATOMIC.
163 */
164 p = kmalloc_track_caller(len, GFP_KERNEL);
165 if (!p) 161 if (!p)
166 return ERR_PTR(-ENOMEM); 162 return ERR_PTR(-ENOMEM);
167 163
@@ -174,6 +170,32 @@ void *memdup_user(const void __user *src, size_t len)
174} 170}
175EXPORT_SYMBOL(memdup_user); 171EXPORT_SYMBOL(memdup_user);
176 172
173/**
174 * vmemdup_user - duplicate memory region from user space
175 *
176 * @src: source address in user space
177 * @len: number of bytes to copy
178 *
179 * Returns an ERR_PTR() on failure. Result may be not
180 * physically contiguous. Use kvfree() to free.
181 */
182void *vmemdup_user(const void __user *src, size_t len)
183{
184 void *p;
185
186 p = kvmalloc(len, GFP_USER);
187 if (!p)
188 return ERR_PTR(-ENOMEM);
189
190 if (copy_from_user(p, src, len)) {
191 kvfree(p);
192 return ERR_PTR(-EFAULT);
193 }
194
195 return p;
196}
197EXPORT_SYMBOL(vmemdup_user);
198
177/* 199/*
178 * strndup_user - duplicate an existing string from user space 200 * strndup_user - duplicate an existing string from user space
179 * @s: The string to duplicate 201 * @s: The string to duplicate