xref: /linux/mm/util.c (revision 1a2f67b459bb7846d4a15924face63eb2683acc2)
130992c97SMatt Mackall #include <linux/slab.h>
230992c97SMatt Mackall #include <linux/string.h>
330992c97SMatt Mackall #include <linux/module.h>
496840aa0SDavi Arnaut #include <linux/err.h>
596840aa0SDavi Arnaut #include <asm/uaccess.h>
630992c97SMatt Mackall 
730992c97SMatt Mackall /**
840c07ae8SPekka Enberg  * __kzalloc - allocate memory. The memory is set to zero.
930992c97SMatt Mackall  * @size: how many bytes of memory are required.
1030992c97SMatt Mackall  * @flags: the type of memory to allocate.
1130992c97SMatt Mackall  */
1240c07ae8SPekka Enberg void *__kzalloc(size_t size, gfp_t flags)
1330992c97SMatt Mackall {
14871751e2SAl Viro 	void *ret = ____kmalloc(size, flags);
1530992c97SMatt Mackall 	if (ret)
1630992c97SMatt Mackall 		memset(ret, 0, size);
1730992c97SMatt Mackall 	return ret;
1830992c97SMatt Mackall }
1940c07ae8SPekka Enberg EXPORT_SYMBOL(__kzalloc);
2030992c97SMatt Mackall 
2130992c97SMatt Mackall /*
2230992c97SMatt Mackall  * kstrdup - allocate space for and copy an existing string
2330992c97SMatt Mackall  *
2430992c97SMatt Mackall  * @s: the string to duplicate
2530992c97SMatt Mackall  * @gfp: the GFP mask used in the kmalloc() call when allocating memory
2630992c97SMatt Mackall  */
2730992c97SMatt Mackall char *kstrdup(const char *s, gfp_t gfp)
2830992c97SMatt Mackall {
2930992c97SMatt Mackall 	size_t len;
3030992c97SMatt Mackall 	char *buf;
3130992c97SMatt Mackall 
3230992c97SMatt Mackall 	if (!s)
3330992c97SMatt Mackall 		return NULL;
3430992c97SMatt Mackall 
3530992c97SMatt Mackall 	len = strlen(s) + 1;
36871751e2SAl Viro 	buf = ____kmalloc(len, gfp);
3730992c97SMatt Mackall 	if (buf)
3830992c97SMatt Mackall 		memcpy(buf, s, len);
3930992c97SMatt Mackall 	return buf;
4030992c97SMatt Mackall }
4130992c97SMatt Mackall EXPORT_SYMBOL(kstrdup);
4296840aa0SDavi Arnaut 
43*1a2f67b4SAlexey Dobriyan /**
44*1a2f67b4SAlexey Dobriyan  * kmemdup - duplicate region of memory
45*1a2f67b4SAlexey Dobriyan  *
46*1a2f67b4SAlexey Dobriyan  * @src: memory region to duplicate
47*1a2f67b4SAlexey Dobriyan  * @len: memory region length
48*1a2f67b4SAlexey Dobriyan  * @gfp: GFP mask to use
49*1a2f67b4SAlexey Dobriyan  */
50*1a2f67b4SAlexey Dobriyan void *kmemdup(const void *src, size_t len, gfp_t gfp)
51*1a2f67b4SAlexey Dobriyan {
52*1a2f67b4SAlexey Dobriyan 	void *p;
53*1a2f67b4SAlexey Dobriyan 
54*1a2f67b4SAlexey Dobriyan 	p = ____kmalloc(len, gfp);
55*1a2f67b4SAlexey Dobriyan 	if (p)
56*1a2f67b4SAlexey Dobriyan 		memcpy(p, src, len);
57*1a2f67b4SAlexey Dobriyan 	return p;
58*1a2f67b4SAlexey Dobriyan }
59*1a2f67b4SAlexey Dobriyan EXPORT_SYMBOL(kmemdup);
60*1a2f67b4SAlexey Dobriyan 
6196840aa0SDavi Arnaut /*
6296840aa0SDavi Arnaut  * strndup_user - duplicate an existing string from user space
6396840aa0SDavi Arnaut  *
6496840aa0SDavi Arnaut  * @s: The string to duplicate
6596840aa0SDavi Arnaut  * @n: Maximum number of bytes to copy, including the trailing NUL.
6696840aa0SDavi Arnaut  */
6796840aa0SDavi Arnaut char *strndup_user(const char __user *s, long n)
6896840aa0SDavi Arnaut {
6996840aa0SDavi Arnaut 	char *p;
7096840aa0SDavi Arnaut 	long length;
7196840aa0SDavi Arnaut 
7296840aa0SDavi Arnaut 	length = strnlen_user(s, n);
7396840aa0SDavi Arnaut 
7496840aa0SDavi Arnaut 	if (!length)
7596840aa0SDavi Arnaut 		return ERR_PTR(-EFAULT);
7696840aa0SDavi Arnaut 
7796840aa0SDavi Arnaut 	if (length > n)
7896840aa0SDavi Arnaut 		return ERR_PTR(-EINVAL);
7996840aa0SDavi Arnaut 
8096840aa0SDavi Arnaut 	p = kmalloc(length, GFP_KERNEL);
8196840aa0SDavi Arnaut 
8296840aa0SDavi Arnaut 	if (!p)
8396840aa0SDavi Arnaut 		return ERR_PTR(-ENOMEM);
8496840aa0SDavi Arnaut 
8596840aa0SDavi Arnaut 	if (copy_from_user(p, s, length)) {
8696840aa0SDavi Arnaut 		kfree(p);
8796840aa0SDavi Arnaut 		return ERR_PTR(-EFAULT);
8896840aa0SDavi Arnaut 	}
8996840aa0SDavi Arnaut 
9096840aa0SDavi Arnaut 	p[length - 1] = '\0';
9196840aa0SDavi Arnaut 
9296840aa0SDavi Arnaut 	return p;
9396840aa0SDavi Arnaut }
9496840aa0SDavi Arnaut EXPORT_SYMBOL(strndup_user);
95