git: 3fa40c5eb8f5 - main - linudebugfs: fix simple_attr_write_common() kernel buffer

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Sun, 14 Jun 2026 22:32:29 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=3fa40c5eb8f57972bf0b329fd2d36af4d2700b8d

commit 3fa40c5eb8f57972bf0b329fd2d36af4d2700b8d
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-06-10 11:04:20 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-06-14 22:31:38 +0000

    linudebugfs: fix simple_attr_write_common() kernel buffer
    
    With 2cf15144daf7e we added a kernel buffer for parsing input copying the
    user buffer into that.  The problem is that we only copy exactly as many
    bytes as the user supplied.  printf 1 would have a write_size of 1, while
    echo 1 would have a write_size of 2 (1\n).  But in order to check and
    parse we need a terminating '\0'.
    
    Overallocate the kernel buffer by 1 and make sure it is always '\0'
    terminated.
    
    Remove the check that the string needs to be of different length than
    the write_size as this will always fail unless the user passes in, e.g.,
    "1\02\n\0" somehow in which case we won't bother as kstrto*ll() will
    not only handle the '\n' but also stop at '\0' and should be fine or
    it will fail and we will error.
    
    In theory we could use a static buffer here as well as we know a maximum
    possible length of digits plus \n and \0 and take a min of that buffer
    length and write_size and then error on a small buffer but given this is
    an optional debug interface, do not bother with any alloc (size).
    
    Fixes:          2cf15144daf7e ("lindebugfs: Pass user buffer pointers ..")
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    dumbbell
    MFC after:      3 days
    Differential Revision: https://reviews.freebsd.org/D57522
---
 sys/compat/linuxkpi/common/src/linux_simple_attr.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_simple_attr.c b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
index e5514194cb33..54eac3bc65fa 100644
--- a/sys/compat/linuxkpi/common/src/linux_simple_attr.c
+++ b/sys/compat/linuxkpi/common/src/linux_simple_attr.c
@@ -163,15 +163,12 @@ simple_attr_write_common(struct file *filp, const char __user *ubuf,
 	if (*ppos != 0 || write_size < 1)
 		return (-EINVAL);
 
-	buf = malloc(write_size, M_LSATTR, M_WAITOK);
+	buf = malloc(write_size + 1, M_LSATTR, M_WAITOK);
 	if (copy_from_user(buf, ubuf, write_size) != 0) {
 		free(buf, M_LSATTR);
 		return (-EFAULT);
 	}
-	if (strnlen(buf, write_size) == write_size) {
-		free(buf, M_LSATTR);
-		return (-EINVAL);
-	}
+	buf[write_size] = '\0';
 
 	mutex_lock(&sattr->mutex);