关于从内核访问用户空间内存
About accessing userspace memory from kernel
我在XNU内核做kext开发,有一个KPI函数叫copyin和它的朋友,类似于copy_from_user在Linux内核
所以我大部分时间都在使用copyin,它在内核space处理数据比相对不稳定的用户space更安全,但有时我需要处理相当大的内存(例如 2MB) 来自 userspace,而我只需要读取,这会是直接访问 userspace 内存的借口吗? (这会导致意想不到的问题吗?)
来自用户space的数据有条目,所以我只需要至少每次读取,此外,我不需要从用户space进程对此内存进行任何写入,我列出了三个我能想到的方法,希望有人能给我建议,我真的很感激!
- 在内核 space 分配足够大小的可分页内存 (IOMallocPageable),并调用 copyin 从用户复制整个数据space
- Alloc 也分配可分页内存,大小足够一个条目,使用copyin 读取和处理然后再次读取到同一内存
- 使用stac禁用smap,直接从用户读取space
第一种方式,如果我不写,那会不会映射到同一个物理映射,所以不需要浪费内存?
哪种方式效率更高?
如果您有用户空间地址,您可以将其重新映射到内核 - 使用 IOMemoryDescriptor::withAddressRange
与相关任务(进程任务)并使用 IOMemoryDescriptor::createMappingInTask
将其映射到内核。
确保权限正确。
友情提示 - stac
/clac
指令被上下文切换代码处理程序覆盖,您必须确保在复制阶段不会调用它。完成了 - 不是很有趣。
我在XNU内核做kext开发,有一个KPI函数叫copyin和它的朋友,类似于copy_from_user在Linux内核
所以我大部分时间都在使用copyin,它在内核space处理数据比相对不稳定的用户space更安全,但有时我需要处理相当大的内存(例如 2MB) 来自 userspace,而我只需要读取,这会是直接访问 userspace 内存的借口吗? (这会导致意想不到的问题吗?)
来自用户space的数据有条目,所以我只需要至少每次读取,此外,我不需要从用户space进程对此内存进行任何写入,我列出了三个我能想到的方法,希望有人能给我建议,我真的很感激!
- 在内核 space 分配足够大小的可分页内存 (IOMallocPageable),并调用 copyin 从用户复制整个数据space
- Alloc 也分配可分页内存,大小足够一个条目,使用copyin 读取和处理然后再次读取到同一内存
- 使用stac禁用smap,直接从用户读取space
第一种方式,如果我不写,那会不会映射到同一个物理映射,所以不需要浪费内存? 哪种方式效率更高?
如果您有用户空间地址,您可以将其重新映射到内核 - 使用 IOMemoryDescriptor::withAddressRange
与相关任务(进程任务)并使用 IOMemoryDescriptor::createMappingInTask
将其映射到内核。
确保权限正确。
友情提示 - stac
/clac
指令被上下文切换代码处理程序覆盖,您必须确保在复制阶段不会调用它。完成了 - 不是很有趣。