【发布时间】:2013-02-04 21:56:08
【问题描述】:
我一直被告知(在书籍和教程中)在将数据从内核空间复制到用户空间时,我们应该使用 copy_to_user() 并且使用 memcpy() 会导致系统出现问题。最近我错误地使用了 memcpy() 并且它工作得非常好,没有任何问题。 为什么我们应该使用 copy_to_user 而不是 memcpy()
我的测试代码(内核模块)是这样的:
static ssize_t test_read(struct file *file, char __user * buf,
size_t len, loff_t * offset)
{
char ani[100];
if (!*offset) {
memset(ani, 'A', 100);
if (memcpy(buf, ani, 100))
return -EFAULT;
*offset = 100;
return *offset;
}
return 0;
}
struct file_operations test_fops = {
.owner = THIS_MODULE,
.read = test_read,
};
static int __init my_module_init(void)
{
struct proc_dir_entry *entry;
printk("We are testing now!!\n");
entry = create_proc_entry("test", S_IFREG | S_IRUGO, NULL);
if (!entry)
printk("Failed to creats proc entry test\n");
entry->proc_fops = &test_fops;
return 0;
}
module_init(my_module_init);
从用户空间应用程序,我正在阅读我的 /proc 条目,一切正常。
查看 copy_to_user() 的源代码表明它也是简单的 memcpy(),我们只是尝试使用 access_ok 并执行 memcpy 检查指针是否有效。
所以我的理解目前是,如果我们确定我们传递的指针,memcpy() 总是可以用来代替 copy_to_user。
如果我的理解不正确,请纠正我,copy_to_user 有效且 memcpy() 失败的任何示例都非常有用。谢谢。
【问题讨论】:
-
因为分页。
-
@Linuxios 抱歉,请您再解释一下。我无法证明内核能够完美地复制,我也无法在 copy_to_user 的源代码中看到与分页相关的任何内容。你能详细说明一下吗?
-
@Sandy:假设性问题:您使用的是具有 16 GB RAM 的 32 位系统。 memcpy 会起作用吗?
-
不要使用 memcpy 作为 copy_to_user!这是马车。
标签: c linux-kernel linux-device-driver memcpy