Linux kernel 从不为char工作的用户复制*

Linux kernel 从不为char工作的用户复制*,linux-kernel,kernel-module,Linux Kernel,Kernel Module,我对内核编程有点陌生,所以请原谅这个问题。本质上,我想发送一个字符串(char*)到内核模块进行打印。很简单 我在用户级代码中包含以下内容: char *text = "some text."; ioctl(fd,OUTPUT_TEST,text); 模块内部有: char *text; case OUTPUT_TEST: copy_from_user(text,(char *)arg,sizeof(char*); 但是,文本仍然为空。这不应该是指向字符串的指针吗 我甚至

我对内核编程有点陌生,所以请原谅这个问题。本质上,我想发送一个字符串(char*)到内核模块进行打印。很简单

我在用户级代码中包含以下内容:

char *text = "some text.";      
ioctl(fd,OUTPUT_TEST,text);
模块内部有:

char *text;
case OUTPUT_TEST:
    copy_from_user(text,(char *)arg,sizeof(char*);
但是,文本仍然为空。这不应该是指向字符串的指针吗

我甚至更加困惑,因为以下方法确实有效:

在用户级别:

typedef struct
{
   int size;
   char *text;
}Message;

  int fd = open ("/proc/ioctl_test", O_RDONLY);
  Message message;
  message.text = "This message was sent via OCTL.";
  message.size = strlen(message.text);

  ioctl(fd,OUTPUT_TEST,message);
在内核空间中:


这很好用。我真的很困惑,希望你们能提供任何帮助

我并不想说得太苛刻,但我认为在编写内核模块之前,您需要先学习一下C:-)

copy_from_user的作用正是顾名思义——它将缓冲区从用户空间提供的缓冲区复制到内核提供的缓冲区。这意味着您需要为它提供内核分配的缓冲区,它不会为您分配缓冲区

您的char*文本将指针分配给缓冲区,但不是缓冲区。您需要自己进行缓冲区分配


请注意,在您的第二个示例中,消息结构被定义为全局或堆栈上(从您的示例中看不出来),因此分配发生并且工作正常。

我无意听起来很苛刻,但我认为在编写内核模块之前,您需要先学习一下C:-)

copy_from_user的作用正是顾名思义——它将缓冲区从用户空间提供的缓冲区复制到内核提供的缓冲区。这意味着您需要为它提供内核分配的缓冲区,它不会为您分配缓冲区

您的char*文本将指针分配给缓冲区,但不是缓冲区。您需要自己进行缓冲区分配


请注意,在您的第二个示例中,消息结构被定义为全局或堆栈上(从您的示例中看不出来),因此分配发生并且有效。

谢谢!我确实认为我需要分配一个缓冲区,这就是消息结构包含消息大小的原因。我仍然不明白为什么在复制结构(它只是一个int和一个指针)时,它也会复制文本缓冲区。此外,我还不明白为什么在来自用户的第一个副本中,文本仍然是空的。不,它不会复制缓冲区,但不应该复制内容(如用户空间指针)?我知道该指针不起作用,但我不确定文本为什么保持空。@kodai:Your
Message
示例根本不复制文本缓冲区-它只复制文本缓冲区的(用户空间)地址。这是一个错误,因为内核永远不应该直接取消对用户空间指针的引用-它不适用于所有体系结构,即使在它工作的地方也不安全。另外,不要忘记需要复制整个字符串<代码>从用户复制(文本,(字符*)参数,大小(字符*)仅复制指针的大小。应该类似于
copy_from_user(text,(char*)arg,strlen(arg)),但我不记得内核代码是否实现了strlen
。谢谢!我确实认为我需要分配一个缓冲区,这就是消息结构包含消息大小的原因。我仍然不明白为什么在复制结构(它只是一个int和一个指针)时,它也会复制文本缓冲区。此外,我还不明白为什么在来自用户的第一个副本中,文本仍然是空的。不,它不会复制缓冲区,但不应该复制内容(如用户空间指针)?我知道该指针不起作用,但我不确定文本为什么保持空。@kodai:Your
Message
示例根本不复制文本缓冲区-它只复制文本缓冲区的(用户空间)地址。这是一个错误,因为内核永远不应该直接取消对用户空间指针的引用-它不适用于所有体系结构,即使在它工作的地方也不安全。另外,不要忘记需要复制整个字符串<代码>从用户复制(文本,(字符*)参数,大小(字符*)仅复制指针的大小。应该类似于
copy_from_user(text,(char*)arg,strlen(arg)),但我不记得内核代码是否实现了strlen
copy_from_user(&message,(Message *)arg,sizeof(Message));