2009-11-08 173 views
9

我已经实现了某种字符设备,我需要copy_ from_user函数的帮助。Linux内核:copy_from_user - 结构与指针

我有一个结构:

struct my_struct{ 

int a; 

int *b; 
}; 

我初始化它在用户空间,并通过使用指针“写”功能my_struct我的字符设备。在内核空间字符设备的“写入”函数中,我将它从* char转换为这种结构。我使用kmalloc为一个结构体分配了一些内存,并将它做到copy_from_user

简单的'int a'可以,但它只复制b值的指针(地址),而不是b指向的值,所以我现在处于内核空间,我正在处理一个指向一个用户空间内存。这是不正确的,我不应该直接访问用户空间指针,我必须copy_from_user结构中的每一个指针,然后使用copy_to_user函数将“读取”函数中的每个指针都复制回来?

回答

6

你在猜测中是正确的。如果您需要访问值*b,则需要使用copy_from_user(和copy_to_user将其更新回用户进程中)。

+2

我还要指出的是,我不认为采取结构与它们的指示任何系统调用或读写控制。即使是那些具有字符串的字符串也会在结构体中有一个字符数组。事实上,为每个指针成员编写代码非常烦人,这可能与此有关。 :-) – asveikau 2009-11-08 23:54:56

+0

@asveikau:'readv()'和'writev()'? – caf 2011-01-02 01:24:47

13

无论您如何获得指针,您都必须始终使用copy_from_user和类似的方法从内核空间访问用户空间内存。由于b是用户空间内存的指针,因此您必须使用copy_from_user来访问它。

这些功能做了两个重要的附加任务:

  1. 他们确保指针指向到用户空间,而不是内核空间。如果没有此检查,用户空间程序可能会读取或写入内核内存,从而绕过正常的安全性。
  2. 它们正确处理页面错误。通常,内核模式下的页面错误会导致OOPS或者恐慌 - copy_*_user函数系列有一个特殊的覆盖,告诉PF处理程序一切正常,应该正常处理错误;并且在该故障无法通过IO满足的情况下(即,什么通常会导致一个SIGSEGVSIGBUS),返回与-EFAULT用户空间之前返回错误代码代替调用者可以做任何必要的清理。