1 #include <linux/mm.h> 2 #include <linux/slab.h> 3 #include <linux/string.h> 4 #include <linux/module.h> 5 #include <linux/err.h> 6 #include <linux/sched.h> 7 #include <asm/uaccess.h> 8 9 /** 10 * kstrdup - allocate space for and copy an existing string 11 * @s: the string to duplicate 12 * @gfp: the GFP mask used in the kmalloc() call when allocating memory 13 */ 14 char *kstrdup(const char *s, gfp_t gfp) 15 { 16 size_t len; 17 char *buf; 18 19 if (!s) 20 return NULL; 21 22 len = strlen(s) + 1; 23 buf = kmalloc_track_caller(len, gfp); 24 if (buf) 25 memcpy(buf, s, len); 26 return buf; 27 } 28 EXPORT_SYMBOL(kstrdup); 29 30 /** 31 * kstrndup - allocate space for and copy an existing string 32 * @s: the string to duplicate 33 * @max: read at most @max chars from @s 34 * @gfp: the GFP mask used in the kmalloc() call when allocating memory 35 */ 36 char *kstrndup(const char *s, size_t max, gfp_t gfp) 37 { 38 size_t len; 39 char *buf; 40 41 if (!s) 42 return NULL; 43 44 len = strnlen(s, max); 45 buf = kmalloc_track_caller(len+1, gfp); 46 if (buf) { 47 memcpy(buf, s, len); 48 buf[len] = '\0'; 49 } 50 return buf; 51 } 52 EXPORT_SYMBOL(kstrndup); 53 54 /** 55 * kmemdup - duplicate region of memory 56 * 57 * @src: memory region to duplicate 58 * @len: memory region length 59 * @gfp: GFP mask to use 60 */ 61 void *kmemdup(const void *src, size_t len, gfp_t gfp) 62 { 63 void *p; 64 65 p = kmalloc_track_caller(len, gfp); 66 if (p) 67 memcpy(p, src, len); 68 return p; 69 } 70 EXPORT_SYMBOL(kmemdup); 71 72 /** 73 * __krealloc - like krealloc() but don't free @p. 74 * @p: object to reallocate memory for. 75 * @new_size: how many bytes of memory are required. 76 * @flags: the type of memory to allocate. 77 * 78 * This function is like krealloc() except it never frees the originally 79 * allocated buffer. Use this if you don't want to free the buffer immediately 80 * like, for example, with RCU. 81 */ 82 void *__krealloc(const void *p, size_t new_size, gfp_t flags) 83 { 84 void *ret; 85 size_t ks = 0; 86 87 if (unlikely(!new_size)) 88 return ZERO_SIZE_PTR; 89 90 if (p) 91 ks = ksize(p); 92 93 if (ks >= new_size) 94 return (void *)p; 95 96 ret = kmalloc_track_caller(new_size, flags); 97 if (ret && p) 98 memcpy(ret, p, ks); 99 100 return ret; 101 } 102 EXPORT_SYMBOL(__krealloc); 103 104 /** 105 * krealloc - reallocate memory. The contents will remain unchanged. 106 * @p: object to reallocate memory for. 107 * @new_size: how many bytes of memory are required. 108 * @flags: the type of memory to allocate. 109 * 110 * The contents of the object pointed to are preserved up to the 111 * lesser of the new and old sizes. If @p is %NULL, krealloc() 112 * behaves exactly like kmalloc(). If @size is 0 and @p is not a 113 * %NULL pointer, the object pointed to is freed. 114 */ 115 void *krealloc(const void *p, size_t new_size, gfp_t flags) 116 { 117 void *ret; 118 119 if (unlikely(!new_size)) { 120 kfree(p); 121 return ZERO_SIZE_PTR; 122 } 123 124 ret = __krealloc(p, new_size, flags); 125 if (ret && p != ret) 126 kfree(p); 127 128 return ret; 129 } 130 EXPORT_SYMBOL(krealloc); 131 132 /** 133 * kzfree - like kfree but zero memory 134 * @p: object to free memory of 135 * 136 * The memory of the object @p points to is zeroed before freed. 137 * If @p is %NULL, kzfree() does nothing. 138 */ 139 void kzfree(const void *p) 140 { 141 size_t ks; 142 void *mem = (void *)p; 143 144 if (unlikely(ZERO_OR_NULL_PTR(mem))) 145 return; 146 ks = ksize(mem); 147 memset(mem, 0, ks); 148 kfree(mem); 149 } 150 EXPORT_SYMBOL(kzfree); 151 152 /* 153 * strndup_user - duplicate an existing string from user space 154 * @s: The string to duplicate 155 * @n: Maximum number of bytes to copy, including the trailing NUL. 156 */ 157 char *strndup_user(const char __user *s, long n) 158 { 159 char *p; 160 long length; 161 162 length = strnlen_user(s, n); 163 164 if (!length) 165 return ERR_PTR(-EFAULT); 166 167 if (length > n) 168 return ERR_PTR(-EINVAL); 169 170 p = kmalloc(length, GFP_KERNEL); 171 172 if (!p) 173 return ERR_PTR(-ENOMEM); 174 175 if (copy_from_user(p, s, length)) { 176 kfree(p); 177 return ERR_PTR(-EFAULT); 178 } 179 180 p[length - 1] = '\0'; 181 182 return p; 183 } 184 EXPORT_SYMBOL(strndup_user); 185 186 #ifndef HAVE_ARCH_PICK_MMAP_LAYOUT 187 void arch_pick_mmap_layout(struct mm_struct *mm) 188 { 189 mm->mmap_base = TASK_UNMAPPED_BASE; 190 mm->get_unmapped_area = arch_get_unmapped_area; 191 mm->unmap_area = arch_unmap_area; 192 } 193 #endif 194 195 int __attribute__((weak)) get_user_pages_fast(unsigned long start, 196 int nr_pages, int write, struct page **pages) 197 { 198 struct mm_struct *mm = current->mm; 199 int ret; 200 201 down_read(&mm->mmap_sem); 202 ret = get_user_pages(current, mm, start, nr_pages, 203 write, 0, pages, NULL); 204 up_read(&mm->mmap_sem); 205 206 return ret; 207 } 208 EXPORT_SYMBOL_GPL(get_user_pages_fast); 209