Linux内核:copy_from_user - 带有指针的结构体

11

我已经实现了一种字符设备,需要帮助处理 copy_from_user 函数。

我有一个结构体:

struct  my_struct{

int a;

int *b;
};

我在用户空间初始化结构体,并使用“write”函数将指向my_struct的指针传递给我的字符设备。在内核空间的字符设备“write”函数中,我将它从*char转换为这种结构。我使用kmalloc为结构体分配一些内存,并使用copy_from_user将其复制到其中。

对于简单的“int a”来说,这没问题,但它只复制指向b值的指针(地址),而不是指向b指向的值,所以现在我在内核空间,正在使用指向用户空间内存的指针。这样做是否不正确,我不应该直接访问用户空间指针,而是必须每次都使用copy_from_user函数复制我的结构体中的每个指针,然后在“read”函数中使用copy_to_user函数将每个指针复制回去?

2个回答

14
无论指针如何获取,都必须始终使用copy_from_user等函数从内核空间访问用户空间内存。由于b是指向用户空间内存的指针,因此必须使用copy_from_user来访问它。
这些函数执行两个重要的额外任务:
  1. 它们确保指针指向用户空间而不是内核空间。如果没有进行此检查,用户空间程序可能能够读取或写入内核内存,从而绕过正常的安全性。
  2. 它们正确处理页面故障。通常在内核模式下发生页面故障会导致OOPS或崩溃 - copy_*_user函数族具有特殊的覆盖,告诉PF处理程序一切正常,应该正常处理故障;如果无法通过IO满足故障(即通常会导致SIGSEGVSIGBUS),则返回错误代码,以便调用者在返回到用户空间之前进行任何必要的清理操作,然后返回-EFAULT

6

你的推测是正确的。如果需要访问值*b,则需要使用copy_from_user(和copy_to_user来更新用户进程中的值)。


2
我还要指出的是,我想不到任何带有指针结构体的系统调用或ioctl。即使那些具有字符串的结构体也会在结构体中使用char数组。对于每个指针成员编写此类代码非常麻烦,这可能与此有关。 :-) - asveikau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接