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。
我正在尝试编写一个字符设备,我正在使用 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。