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 * strndup_user - duplicate an existing string from user space 134 * @s: The string to duplicate 135 * @n: Maximum number of bytes to copy, including the trailing NUL. 136 */ 137 char *strndup_user(const char __user *s, long n) 138 { 139 char *p; 140 long length; 141 142 length = strnlen_user(s, n); 143 144 if (!length) 145 return ERR_PTR(-EFAULT); 146 147 if (length > n) 148 return ERR_PTR(-EINVAL); 149 150 p = kmalloc(length, GFP_KERNEL); 151 152 if (!p) 153 return ERR_PTR(-ENOMEM); 154 155 if (copy_from_user(p, s, length)) { 156 kfree(p); 157 return ERR_PTR(-EFAULT); 158 } 159 160 p[length - 1] = '\0'; 161 162 return p; 163 } 164 EXPORT_SYMBOL(strndup_user); 165 166 #ifndef HAVE_ARCH_PICK_MMAP_LAYOUT 167 void arch_pick_mmap_layout(struct mm_struct *mm) 168 { 169 mm->mmap_base = TASK_UNMAPPED_BASE; 170 mm->get_unmapped_area = arch_get_unmapped_area; 171 mm->unmap_area = arch_unmap_area; 172 } 173 #endif 174 175 int __attribute__((weak)) get_user_pages_fast(unsigned long start, 176 int nr_pages, int write, struct page **pages) 177 { 178 struct mm_struct *mm = current->mm; 179 int ret; 180 181 down_read(&mm->mmap_sem); 182 ret = get_user_pages(current, mm, start, nr_pages, 183 write, 0, pages, NULL); 184 up_read(&mm->mmap_sem); 185 186 return ret; 187 } 188 EXPORT_SYMBOL_GPL(get_user_pages_fast); 189