【问题标题】:Weird behavior when passing strings to kernel module via IOCTL通过 IOCTL 将字符串传递给内核模块时的奇怪行为
【发布时间】:2020-10-19 23:59:45
【问题描述】:

我使用指向带有参数的用户空间结构的指针将字符串传递给 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);

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

【问题讨论】:

  • “正确的字符串长度”是否包含终止空字符?
  • 我用strlen 得到它,包括它吗?
  • 不,strlen 不包括在内。

标签: c module linux-kernel ioctl


【解决方案1】:

要通过%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);

【讨论】:

  • 如果kern_path[] 没有空间容纳null 字符,代码或许可以使用printk(KERN_ALERT "Copied string: %.*s.\n", (int) path_len, kern_path);。这适用于printf() - 不太确定printk()。使用"%.*s",不需要空字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多