diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-12-24 00:06:05 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-01-04 10:20:19 -0500 |
commit | e9d408e107db9a554b36c3a79f67b37dd3e16da0 (patch) | |
tree | 97383e40e388aa302828ffb2ddd845b257109118 /mm/util.c | |
parent | 74bf8efb5fa6e958d2d7c7917b8bb672085ec0c6 (diff) |
new helper: memdup_user_nul()
Similar to memdup_user(), except that allocated buffer is one byte
longer and '\0' is stored after the copied data.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm/util.c')
-rw-r--r-- | mm/util.c | 31 |
1 files changed, 31 insertions, 0 deletions
@@ -176,6 +176,37 @@ char *strndup_user(const char __user *s, long n) | |||
176 | } | 176 | } |
177 | EXPORT_SYMBOL(strndup_user); | 177 | EXPORT_SYMBOL(strndup_user); |
178 | 178 | ||
179 | /** | ||
180 | * memdup_user_nul - duplicate memory region from user space and NUL-terminate | ||
181 | * | ||
182 | * @src: source address in user space | ||
183 | * @len: number of bytes to copy | ||
184 | * | ||
185 | * Returns an ERR_PTR() on failure. | ||
186 | */ | ||
187 | void *memdup_user_nul(const void __user *src, size_t len) | ||
188 | { | ||
189 | char *p; | ||
190 | |||
191 | /* | ||
192 | * Always use GFP_KERNEL, since copy_from_user() can sleep and | ||
193 | * cause pagefault, which makes it pointless to use GFP_NOFS | ||
194 | * or GFP_ATOMIC. | ||
195 | */ | ||
196 | p = kmalloc_track_caller(len + 1, GFP_KERNEL); | ||
197 | if (!p) | ||
198 | return ERR_PTR(-ENOMEM); | ||
199 | |||
200 | if (copy_from_user(p, src, len)) { | ||
201 | kfree(p); | ||
202 | return ERR_PTR(-EFAULT); | ||
203 | } | ||
204 | p[len] = '\0'; | ||
205 | |||
206 | return p; | ||
207 | } | ||
208 | EXPORT_SYMBOL(memdup_user_nul); | ||
209 | |||
179 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, | 210 | void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, |
180 | struct vm_area_struct *prev, struct rb_node *rb_parent) | 211 | struct vm_area_struct *prev, struct rb_node *rb_parent) |
181 | { | 212 | { |