copy_to_user vs memcpy

我一直被告知(在书籍和教程中),在将数据从内核空间复制到用户空间时,我们应该使用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()失败的任何示例都非常有用 。 谢谢。

这有几个原因。

一,安全。 因为内核可以写入它想要的任何地址,如果你只使用你得到的用户空间地址并使用memcpy ,攻击者就可以写入另一个进程的页面,这是一个巨大的安全问题。 copy_to_user检查当前进程是否可写入目标页面。

还有一些架构考虑因素。 例如,在x86上,目标页面必须固定在内存中。 在某些体系结构上,您可能需要特殊说明。 等等。 Linux内核非常便携的目标需要这种抽象。