git: 59642e07f427 - main - linuxkpi: add strncpy_from_user()

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Sat, 17 Oct 2026 19:56:01 UTC
The branch main has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=59642e07f4272d56d5a2b68169e388123d01b03b

commit 59642e07f4272d56d5a2b68169e388123d01b03b
Author:     Denis Borovikov <denis.borovikov@gmail.com>
AuthorDate: 2026-10-17 19:55:17 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2026-10-17 19:55:17 +0000

    linuxkpi: add strncpy_from_user()
    
    Same semantics as Linux: returns the string length without the NUL,
    count if the string was truncated, or -EFAULT. Implemented with
    copyinstr(9). Unlike linux_copyin() it does not translate the remapped
    ioctl argument window; its user, drm/virtio, passes a pointer taken
    from the ioctl payload, so that is not needed.
    
    Signed-off-by:  Denis Borovikov <denis.borovikov@gmail.com>
    Reviewed by:    wulf
    Differential Revision:  https://reviews.freebsd.org/D60198
---
 sys/compat/linuxkpi/common/include/linux/uaccess.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/uaccess.h b/sys/compat/linuxkpi/common/include/linux/uaccess.h
index 97fb2e3a7420..9f31dc562157 100644
--- a/sys/compat/linuxkpi/common/include/linux/uaccess.h
+++ b/sys/compat/linuxkpi/common/include/linux/uaccess.h
@@ -32,6 +32,7 @@
 #define	_LINUXKPI_LINUX_UACCESS_H_
 
 #include <sys/param.h>
+#include <sys/systm.h>
 #include <sys/lock.h>
 #include <sys/proc.h>
 
@@ -119,4 +120,20 @@ __copy_from_user_inatomic(void *to, const void __user *from,
 #define	copy_from_user_inatomic_nontemporal(to, from, n)	\
 	__copy_from_user_inatomic((to), (from), (n))
 
+static inline long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	size_t done;
+	int error;
+
+	if (count <= 0)
+		return (0);
+	error = copyinstr(src, dst, count, &done);
+	if (error == 0)
+		return ((long)done - 1);	/* done includes the NUL */
+	if (error == ENAMETOOLONG)
+		return (count);			/* truncated, as Linux */
+	return (-EFAULT);
+}
+
 #endif					/* _LINUXKPI_LINUX_UACCESS_H_ */