git: fbaa247e8b7a - stable/15 - Implement vmemdup_{array}_user
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 22 Sep 2026 15:48:53 UTC
The branch stable/15 has been updated by wulf:
URL: https://cgit.FreeBSD.org/src/commit/?id=fbaa247e8b7a47af307255b01c81943b35af4486
commit fbaa247e8b7a47af307255b01c81943b35af4486
Author: David Heidelberg <david@ixit.cz>
AuthorDate: 2026-09-15 20:17:52 +0000
Commit: Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2026-09-22 15:47:03 +0000
Implement vmemdup_{array}_user
This is what FreeBSD now does for memdup_user and memdup_array_user
(which is wrong for memdup, but correct for vmemdup).
The amdgpu DRM driver started this in Linux ~6.12.86+
Reviewed by: wulf
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D57444
(cherry picked from commit 302c6d25da6907ec762ff8937fa86d380743b000)
---
sys/compat/linuxkpi/common/include/linux/string.h | 26 +++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/sys/compat/linuxkpi/common/include/linux/string.h b/sys/compat/linuxkpi/common/include/linux/string.h
index b195dcc8fe9b..9df4ce0d796d 100644
--- a/sys/compat/linuxkpi/common/include/linux/string.h
+++ b/sys/compat/linuxkpi/common/include/linux/string.h
@@ -72,6 +72,21 @@ memdup_user(const void *ptr, size_t len)
return (retval);
}
+static inline void *
+vmemdup_user(const void *ptr, size_t len)
+{
+ void *retval;
+ int error;
+
+ retval = malloc(len, M_KMALLOC, M_WAITOK);
+ error = linux_copyin(ptr, retval, len);
+ if (error != 0) {
+ free(retval, M_KMALLOC);
+ return (ERR_PTR(error));
+ }
+ return (retval);
+}
+
static inline void *
memdup_user_nul(const void *ptr, size_t len)
{
@@ -99,6 +114,17 @@ memdup_array_user(const void *src, size_t n, size_t size)
return (memdup_user(src, len));
}
+static inline void *
+vmemdup_array_user(const void *src, size_t n, size_t size)
+{
+ size_t len;
+
+ if (check_mul_overflow(n, size, &len))
+ return (ERR_PTR(-EOVERFLOW));
+
+ return (vmemdup_user(src, len));
+}
+
static inline void *
kmemdup(const void *src, size_t len, gfp_t gfp)
{