【发布时间】:2018-05-22 18:55:45
【问题描述】:
我在XNU内核做kext开发,有一个KPI函数叫copyin和它的朋友,类似于Linux内核的copy_from_user
所以我大部分时间都在使用 copyin,它在内核空间而不是相对易变的用户空间处理数据更安全,但有时我需要处理来自用户空间的大量内存(例如 2MB),我只需要读取,这会是直接访问用户空间内存的借口吗? (这会导致意想不到的问题吗?)
来自用户空间的数据有条目,所以我至少每次都需要读取,此外我不需要从用户空间进程对此内存进行任何写入,我列出了三种我能想到的方式,希望有人可以给我建议,我真的很感激!
- 在内核空间分配足够大小的可分页内存 (IOMallocPageable),并调用 copyin 从用户空间复制全部数据
- Alloc 也分配可分页内存,大小足以容纳一个条目,使用 copyin 读取并处理然后再次读取到同一内存中
- 使用stac禁用smap,直接从用户空间读取
第一种方式,如果我不写,那可以映射到相同的物理地图,所以不需要浪费内存吗? 哪种方式效率更高?
【问题讨论】:
-
您在处理什么样的数据?如果数据在您处理时发生变化怎么办?
-
(这会导致意外问题吗?) 根据您的操作,它可能会导致各种安全问题。如果出于安全目的验证数据,则该过程可以更改数据。例如,假设您的驱动程序将读取文件并将数据返回给进程。您读入文件名,并验证用户有权打开和读取它。然后打开它,读取它,并将数据传递给进程。在权限检查和实际读取数据之间,进程将名称更改为
/etc/shadow,并获取所有用户的哈希密码以进行离线破解。 -
条目结构列表,我必须阅读它们中的每一个进行计算。我确保在读取数据期间 proc 被锁定
-
@cocoa 你确定你能保证用户空间线程被停止吗?别人的简历是什么?如果此内存也可用于另一个进程(共享映射)怎么办?
-
@cocoa 尽管访问用户空间内存可能是可能的,但可能很难正确地做到这一点。根据您处理数据的方式,您可能会考虑使用 statefull API。您的情况可能类似于也可能不类似于 C10k 问题,该问题通过从
poll/select切换到epoll/kqueue来解决。
标签: c linux memory linux-kernel xnu