55#include <linux/compiler.h> /* for inline */
66#include <linux/types.h> /* for size_t */
77#include <linux/stddef.h> /* for NULL */
8+ #include <linux/err.h> /* for ERR_PTR() */
89#include <linux/errno.h> /* for E2BIG */
10+ #include <linux/overflow.h> /* for check_mul_overflow() */
911#include <linux/stdarg.h>
1012#include <uapi/linux/string.h>
1113
@@ -14,6 +16,44 @@ extern void *memdup_user(const void __user *, size_t);
1416extern void * vmemdup_user (const void __user * , size_t );
1517extern void * memdup_user_nul (const void __user * , size_t );
1618
19+ /**
20+ * memdup_array_user - duplicate array from user space
21+ * @src: source address in user space
22+ * @n: number of array members to copy
23+ * @size: size of one array member
24+ *
25+ * Return: an ERR_PTR() on failure. Result is physically
26+ * contiguous, to be freed by kfree().
27+ */
28+ static inline void * memdup_array_user (const void __user * src , size_t n , size_t size )
29+ {
30+ size_t nbytes ;
31+
32+ if (check_mul_overflow (n , size , & nbytes ))
33+ return ERR_PTR (- EOVERFLOW );
34+
35+ return memdup_user (src , nbytes );
36+ }
37+
38+ /**
39+ * vmemdup_array_user - duplicate array from user space
40+ * @src: source address in user space
41+ * @n: number of array members to copy
42+ * @size: size of one array member
43+ *
44+ * Return: an ERR_PTR() on failure. Result may be not
45+ * physically contiguous. Use kvfree() to free.
46+ */
47+ static inline void * vmemdup_array_user (const void __user * src , size_t n , size_t size )
48+ {
49+ size_t nbytes ;
50+
51+ if (check_mul_overflow (n , size , & nbytes ))
52+ return ERR_PTR (- EOVERFLOW );
53+
54+ return vmemdup_user (src , nbytes );
55+ }
56+
1757/*
1858 * Include machine specific inline routines
1959 */
0 commit comments