1 #include <linux/slab.h> 2 #include <linux/string.h> 3 #include <linux/module.h> 4 #include <linux/err.h> 5 #include <asm/uaccess.h> 6 7 /** 8 * kstrdup - allocate space for and copy an existing string 9 * 10 * @s: the string to duplicate 11 * @gfp: the GFP mask used in the kmalloc() call when allocating memory 12 */ 13 char *kstrdup(const char *s, gfp_t gfp) 14 { 15 size_t len; 16 char *buf; 17 18 if (!s) 19 return NULL; 20 21 len = strlen(s) + 1; 22 buf = kmalloc_track_caller(len, gfp); 23 if (buf) 24 memcpy(buf, s, len); 25 return buf; 26 } 27 EXPORT_SYMBOL(kstrdup); 28 29 /** 30 * kmemdup - duplicate region of memory 31 * 32 * @src: memory region to duplicate 33 * @len: memory region length 34 * @gfp: GFP mask to use 35 */ 36 void *kmemdup(const void *src, size_t len, gfp_t gfp) 37 { 38 void *p; 39 40 p = kmalloc_track_caller(len, gfp); 41 if (p) 42 memcpy(p, src, len); 43 return p; 44 } 45 EXPORT_SYMBOL(kmemdup); 46 47 /** 48 * krealloc - reallocate memory. The contents will remain unchanged. 49 * @p: object to reallocate memory for. 50 * @new_size: how many bytes of memory are required. 51 * @flags: the type of memory to allocate. 52 * 53 * The contents of the object pointed to are preserved up to the 54 * lesser of the new and old sizes. If @p is %NULL, krealloc() 55 * behaves exactly like kmalloc(). If @size is 0 and @p is not a 56 * %NULL pointer, the object pointed to is freed. 57 */ 58 void *krealloc(const void *p, size_t new_size, gfp_t flags) 59 { 60 void *ret; 61 size_t ks; 62 63 if (unlikely(!new_size)) { 64 kfree(p); 65 return ZERO_SIZE_PTR; 66 } 67 68 ks = ksize(p); 69 if (ks >= new_size) 70 return (void *)p; 71 72 ret = kmalloc_track_caller(new_size, flags); 73 if (ret) { 74 memcpy(ret, p, min(new_size, ks)); 75 kfree(p); 76 } 77 return ret; 78 } 79 EXPORT_SYMBOL(krealloc); 80 81 /* 82 * strndup_user - duplicate an existing string from user space 83 * 84 * @s: The string to duplicate 85 * @n: Maximum number of bytes to copy, including the trailing NUL. 86 */ 87 char *strndup_user(const char __user *s, long n) 88 { 89 char *p; 90 long length; 91 92 length = strnlen_user(s, n); 93 94 if (!length) 95 return ERR_PTR(-EFAULT); 96 97 if (length > n) 98 return ERR_PTR(-EINVAL); 99 100 p = kmalloc(length, GFP_KERNEL); 101 102 if (!p) 103 return ERR_PTR(-ENOMEM); 104 105 if (copy_from_user(p, s, length)) { 106 kfree(p); 107 return ERR_PTR(-EFAULT); 108 } 109 110 p[length - 1] = '\0'; 111 112 return p; 113 } 114 EXPORT_SYMBOL(strndup_user); 115