首页 > 解决方案 > 通过 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);

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

标签: cmodulelinux-kernelioctl

解决方案


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

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

推荐阅读