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

时间:2015-10-28 05:42:42

标签: c linux string kernel

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

//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中计数。

e.g。缓冲区长度为4:

echo 123 > /dev/my_chardev
但是,

strcnpy_from_user可能会复制超过4个字节。 根据文档,最后一个参数是“要复制的最大字节数”。但这似乎不是真的。

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

编辑:

正如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;

1 个答案:

答案 0 :(得分:1)

与常规strncpy一样,如果字符串与您指定的最大长度(或更长)一样长,则您使用的函数不会终止缓冲区。如果len计算写入设备的实际字符数,并且您希望将它们放入C字符串中,则必须记住在分配大小中添加1并将最后一个字节设置为0,否则您将继续有一个非终止字符串。

但是,如果你仍在努力克服C字符串基础并且NULL终止vs计数字符串远离内核模式,如果你想使用虚拟文件系统使用FUSE。