为什么当我使用copy_from_user时,一些模糊的字符添加到原始缓冲区?

Mil*_*avi 2 c kernel kernel-module linux-device-driver linux-kernel

我在内核模块中创建了WRITE_IOCTL,并在用户模式下调用它:

ioctl(fd, WRITE_IOCTL, "Hello, Kernel!");
Run Code Online (Sandbox Code Playgroud)

在内核模式中,我有:

static int device_ioctl(struct file *filp,
    unsigned int cmd, unsigned long args) {
  char buff[14];

  switch (cmd) {
  case WRITE_IOCTL:
    copy_from_user( buff,(char *)args, 14);
    printk("This message received from User Space: %s\n", buff);
    break;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行这个ioctl时,我在/var/log/kern.log中有类似的东西:

This message received from User Space: Hello, Kernel!vE?
This message received from User Space: Hello, Kernel!M?
This message received from User Space: Hello, Kernel!M?
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题??

The*_*ask 5

可能copy_from_user()不会放置null-byte-terminattor,因为args它大于或等于你的n并且printk()期望一个null-terminatted,所以你正在访问垃圾值.要解决这个问题,请将自己初始化buf为零:

  char buff[14 + 1] = {0}; // +1 for make room to 0-byte-terminattor.
Run Code Online (Sandbox Code Playgroud)

它将buf用零填充所有字节.

编辑:

正如评论中提到的@caf,你需要留出一些空格来使用null-byte-terminattor.因此,不是准确地给出缓冲区大小来运行,而是将它传递给n-1,这样函数将循环unl n然后放入空字节.

  • @Khajavi:请注意,您还需要将缓冲区扩展为`[15]`,以便为null终止符腾出空间. (2认同)