我正在尝试编写一个字符设备,我正在使用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;
答案 0 :(得分:1)
与常规strncpy
一样,如果字符串与您指定的最大长度(或更长)一样长,则您使用的函数不会终止缓冲区。如果len
计算写入设备的实际字符数,并且您希望将它们放入C字符串中,则必须记住在分配大小中添加1并将最后一个字节设置为0,否则您将继续有一个非终止字符串。
但是请,如果你仍在努力克服C字符串基础并且NULL终止vs计数字符串远离内核模式,如果你想使用虚拟文件系统使用FUSE。