xref: /linux/mm/util.c (revision d91958815d214ea365b98cbff6215383897edcb6)
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 <asm/uaccess.h>
7 
8 /**
9  * kstrdup - allocate space for and copy an existing string
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  * kstrndup - allocate space for and copy an existing string
31  * @s: the string to duplicate
32  * @max: read at most @max chars from @s
33  * @gfp: the GFP mask used in the kmalloc() call when allocating memory
34  */
35 char *kstrndup(const char *s, size_t max, gfp_t gfp)
36 {
37 	size_t len;
38 	char *buf;
39 
40 	if (!s)
41 		return NULL;
42 
43 	len = strnlen(s, max);
44 	buf = kmalloc_track_caller(len+1, gfp);
45 	if (buf) {
46 		memcpy(buf, s, len);
47 		buf[len] = '\0';
48 	}
49 	return buf;
50 }
51 EXPORT_SYMBOL(kstrndup);
52 
53 /**
54  * kmemdup - duplicate region of memory
55  *
56  * @src: memory region to duplicate
57  * @len: memory region length
58  * @gfp: GFP mask to use
59  */
60 void *kmemdup(const void *src, size_t len, gfp_t gfp)
61 {
62 	void *p;
63 
64 	p = kmalloc_track_caller(len, gfp);
65 	if (p)
66 		memcpy(p, src, len);
67 	return p;
68 }
69 EXPORT_SYMBOL(kmemdup);
70 
71 /**
72  * krealloc - reallocate memory. The contents will remain unchanged.
73  * @p: object to reallocate memory for.
74  * @new_size: how many bytes of memory are required.
75  * @flags: the type of memory to allocate.
76  *
77  * The contents of the object pointed to are preserved up to the
78  * lesser of the new and old sizes.  If @p is %NULL, krealloc()
79  * behaves exactly like kmalloc().  If @size is 0 and @p is not a
80  * %NULL pointer, the object pointed to is freed.
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 		kfree(p);
89 		return ZERO_SIZE_PTR;
90 	}
91 
92 	if (p)
93 		ks = ksize(p);
94 
95 	if (ks >= new_size)
96 		return (void *)p;
97 
98 	ret = kmalloc_track_caller(new_size, flags);
99 	if (ret && p) {
100 		memcpy(ret, p, ks);
101 		kfree(p);
102 	}
103 	return ret;
104 }
105 EXPORT_SYMBOL(krealloc);
106 
107 /*
108  * strndup_user - duplicate an existing string from user space
109  * @s: The string to duplicate
110  * @n: Maximum number of bytes to copy, including the trailing NUL.
111  */
112 char *strndup_user(const char __user *s, long n)
113 {
114 	char *p;
115 	long length;
116 
117 	length = strnlen_user(s, n);
118 
119 	if (!length)
120 		return ERR_PTR(-EFAULT);
121 
122 	if (length > n)
123 		return ERR_PTR(-EINVAL);
124 
125 	p = kmalloc(length, GFP_KERNEL);
126 
127 	if (!p)
128 		return ERR_PTR(-ENOMEM);
129 
130 	if (copy_from_user(p, s, length)) {
131 		kfree(p);
132 		return ERR_PTR(-EFAULT);
133 	}
134 
135 	p[length - 1] = '\0';
136 
137 	return p;
138 }
139 EXPORT_SYMBOL(strndup_user);
140 
141 #ifndef HAVE_ARCH_PICK_MMAP_LAYOUT
142 void arch_pick_mmap_layout(struct mm_struct *mm)
143 {
144 	mm->mmap_base = TASK_UNMAPPED_BASE;
145 	mm->get_unmapped_area = arch_get_unmapped_area;
146 	mm->unmap_area = arch_unmap_area;
147 }
148 #endif
149