内核模式-通过共享内存的用户模式通信,而不使用系统线程

问题描述 投票:2回答:2

我已经学习了如何将共享内存实现为两个用户模式进程之间的通信方法。但是我很好奇内核用户模式通信如何完成。

我想知道是否可以在不创建系统线程的情况下实现通过使用共享内存(根本不使用IOCTL!)的内核模式和用户模式之间的通信。

c++ c shared-memory kernel-module windows-kernel
2个回答
0
投票

共享内存和内核线程是正交的东西。内核始终可以访问任何进程的整个地址空间。必要时,内核可以从系统调用,中断处理程序,计时器回调或内核线程访问它。


0
投票

使用共享内存进行通信的问题之一是与调度程序之间没有合作。特别;在数据到达/更改之前,没有办法阻止任务(因此它不占用CPU时间),然后在数据到达/更改时取消阻止。

对于用户空间和内核之间的通信,您将遇到相同的问题。例如。用户空间代码修改“与内核共享”内存中的数据,内核不知道是否/何时发生;因此(为避免内核浪费CPU时间不断轮询共享内存),用户空间代码必须使用普通的内核调用说“嘿,现在看共享内存!”,但是如果您使用的是普通内核调用无论如何,您只需要传递一个指向数据的指针即可,而无需使用共享内存。

使用共享内存进行通信的另一个问题是安全风险。具体来说,任务可以看到数据已到达/已更改,请验证新数据以确保其可接受,然后恶意攻击者可以在数据经过验证后更改数据,然后任务可以对“已验证”的数据进行操作。一个非常简单的示例就是“ if(new_value_in_shared_memory < MAX_VALUE) { myPrivateArray[new_value_in_shared_memory]++;”之类的内容(恶意攻击者在检查后更改了new_value_in_shared_memory,诱使任务修改了不应该执行的内容)。对于彼此信任的任务(例如,您的代码与代码的fork()通信),这根本不是问题;当参与者不相互信任(例如内核不信任用户空间代码)时,这将是一个巨大的痛苦(犯错误和被当当当头非常容易)。防范这种攻击的最简单方法是将数据从共享内存复制到专用缓冲区中,然后进行验证(知道攻击者无法修改副本),然后使用数据。这种复制会增加开销,并且几乎破坏了共享内存的任何性能优势。

对于“与内核通信的用户空间”,有几种可能的选择-内核可以在“验证然后使用”阶段中挂起可以访问共享内存的所有线程(这会造成性能损失,尤其是对于多CPU系统);并且内核可以在“验证然后使用”阶段(例如,对于多线程用户而言,这将是性能灾难)在执行“验证然后使用”阶段时执行虚拟内存管理技巧(例如,将基础页面设置为“如果用户空间试图对其进行修改,则页面错误”状态) -CPU系统)。

注意,“内核调用接受指向用户空间中数据的指针”和“内核调用依赖于用户空间任务堆栈中的数据”会发生相同类型的“验证后修改”安全​​风险。然而;对于这两种情况(不涉及共享内存,但涉及“内核访问任务的普通内存”),通常内核实际上并不访问数据,而只是传输数据。例如,对于write(),内核可能会将数据转发到文件系统代码(而不涉及数据本身),后者可能将数据转发到存储设备驱动程序(而无需涉及数据本身),后者可能会将数据传输到硬盘驱动器(不触摸数据本身)。

© www.soinside.com 2019 - 2024. All rights reserved.