通过 IOCTL 将字符串传递给内核模块时的奇怪行为

Weird behavior when passing strings to kernel module via IOCTL

我正在使用指向带有参数的用户空间结构的指针将字符串传递给 IOCTL 函数。我的结构包含一个指向字符串的指针,我将它复制到本地缓冲区然后使用它。当我从用户空间打印字符串时,它显示正确。然而,当我从内核模块 printk 它时,我得到了一些奇怪的尾随字符,即使我将它复制到一个内核分配的字符串中,该字符串的长度恰好正确(从用户空间提供)并打印该字符串。这不仅是一个打印错误,因为我传递的字符串是文件路径,如果我尝试使用这些字符串创建文件,我会得到一个具有相同乱码名称的文件。这是我在 IOCTL 中所做的:

    char *path = ((struct sparams*) ioctl_param)->path;
    printk(KERN_ALERT "User provided string: %s.\n", path);

    size_t path_len = ((struct sparams*) ioctl_param)->path_len;
    char kern_path[path_len + TRAILING]; // I leave some trailing bytes because I want to add a suffix later
    copy_from_user(kern_path, path, path_len);
    printk(KERN_ALERT "Copied string: %s.\n", kern_path);

在这两种情况下,在将常规字符串作为参数传递后,我都会得到一些乱码。我可能做错了什么?

要通过 %s 打印的字符串的末尾必须有终止空字符。

copy_from_user(kern_path, path, path_len);
kern_path[path_len] = '[=10=]'; /* add this */
printk(KERN_ALERT "Copied string: %s.\n", kern_path);