【问题标题】:About accessing userspace memory from kernel关于从内核访问用户空间内存
【发布时间】:2018-05-22 18:55:45
【问题描述】:

我在XNU内核做kext开发,有一个KPI函数叫copyin和它的朋友,类似于Linux内核的copy_from_user

所以我大部分时间都在使用 copyin,它在内核空间而不是相对易变的用户空间处理数据更安全,但有时我需要处理来自用户空间的大量内存(例如 2MB),我只需要读取,这会是直接访问用户空间内存的借口吗? (这会导致意想不到的问题吗?)

来自用户空间的数据有条目,所以我至少每次都需要读取,此外我不需要从用户空间进程对此内存进行任何写入,我列出了三种我能想到的方式,希望有人可以给我建议,我真的很感激!

  1. 在内核空间分配足够大小的可分页内存 (IOMallocPageable),并调用 copyin 从用户空间复制全部数据
  2. Alloc 也分配可分页内存,大小足以容纳一个条目,使用 copyin 读取并处理然后再次读取到同一内存中
  3. 使用stac禁用smap,直接从用户空间读取

第一种方式,如果我不写,那可以映射到相同的物理地图,所以不需要浪费内存吗? 哪种方式效率更高?

【问题讨论】:

  • 您在处理什么样的数据?如果数据在您处理时发生变化怎么办?
  • (这会导致意外问题吗?) 根据您的操作,它可能会导致各种安全问题。如果出于安全目的验证数据,则该过程可以更改数据。例如,假设您的驱动程序将读取文件并将数据返回给进程。您读入文件名,并验证用户有权打开和读取它。然后打开它,读取它,并将数据传递给进程。在权限检查和实际读取数据之间,进程将名称更改为/etc/shadow,并获取所有用户的哈希密码以进行离线破解。
  • 条目结构列表,我必须阅读它们中的每一个进行计算。我确保在读取数据期间 proc 被锁定
  • @cocoa 你确定你能保证用户空间线程被停止吗?别人的简历是什么?如果此内存也可用于另一个进程(共享映射)怎么办?
  • @cocoa 尽管访问用户空间内存可能是可能的,但可能很难正确地做到这一点。根据您处理数据的方式,您可能会考虑使用 statefull API。您的情况可能类似于也可能不类似于 C10k 问题,该问题通过从 poll/select 切换到 epoll/kqueue 来解决。

标签: c linux memory linux-kernel xnu


【解决方案1】:

如果您有用户空间地址,您可以将其重新映射到内核 - 将 IOMemoryDescriptor::withAddressRange 与相关任务(进程任务)一起使用,并使用 IOMemoryDescriptor::createMappingInTask 将其映射到内核。

确保权限正确。

只是一个友好的提示 - stac/clac 指令被上下文切换代码处理程序覆盖,您必须确保在复制阶段不会调用它。完成了 - 不是很有趣。

【讨论】:

  • 非常好的建议,有助于将用户空间内存映射到内核空间或将内核内存映射到用户空间!
猜你喜欢
  • 2018-06-30
  • 2012-05-17
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
  • 2012-02-08
  • 2019-12-27
相关资源
最近更新 更多