Linux 内核:strncpy_from_user() 复制了太多字节

Linux Kernel: strncpy_from_user() copying too many bytes

我正在尝试编写一个字符设备,我正在使用 strncpy_from_user 从用户复制到内核 space。但是,它几乎总是复制过多的数据。我这样做的方式是:

//len is buffer length.
tmp = (struct msg_list *)kmalloc(sizeof(struct msg_list),GFP_ATOMIC);
tmp->msg = (char*)kmalloc(len,GFP_ATOMIC);

strncpy_from_user(tmp->msg,buff,len);

缓冲区长度通常输出 1+ 个看到的字符,我认为这是因为它在尾随 NUL 中计数。

例如以下缓冲区长度为 4:

echo 123 > /dev/my_chardev
然而,

strcnpy_from_user 可能会复制超过 4 个字节。 根据文档,最后一个参数是 "The maximum numbers of bytes to copy"。但这似乎不是真的。

我尝试手动设置 (temp->msg)[len-1] = 0,但这似乎会导致问题(无限循环和段错误)。将字符串从用户安全地复制到内核的最佳方法是什么 space?

编辑:

正如 Matteo 在评论中提到的,echo 默认写一个 \n,他还指出尾随 NUL 确实对 read/write 系统调用没有任何意义.这是对我有用的解决方案:

tmp = (struct msg_list *)kmalloc(sizeof(struct msg_list),GFP_ATOMIC);
tmp->msg = (char*)kmalloc(len+1,GFP_ATOMIC);

strncpy_from_user(tmp->msg,buff,len);

(tmp->msg)[len]=0;

与常规 strncpy 一样,如果字符串与指定的最大长度一样长(或更长),您使用的函数不会终止缓冲区。如果len统计实际写入设备的字符数,而你想把它们放在一个C字符串中,你必须记得在分配大小中加1并将最后一个字节设置为0,否则你会周围有一个未终止的字符串。

但是,如果你还在为 C 字符串基础和 NULL 终止与计数字符串而苦苦挣扎,请远离内核模式,如果你想玩虚拟文件系统,请使用 FUSE。