想发财的荒野 · 外键的好处_yaochongchong的博客 ...· 1 年前 · |
会开车的罐头 · lua脚本简单编辑及常用指令_原来的1024 ...· 1 年前 · |
淡定的米饭 · C#基础 string Trim ...· 1 年前 · |
开朗的熊猫 · 对对象进行排序 - PowerShell ...· 1 年前 · |
我已经学习了如何实现共享内存作为两个用户模式进程之间的通信方法。但我很好奇如何实现内核-用户模式的通信。
我想知道内核模式和用户模式之间是否通过共享内存进行通信(根本不用IOCTL!)可以在不创建系统线程的情况下实现。
更新:例如,用户模式程序或内核模式驱动程序在内存中分配一个空间,并且都使用这个空间与指针进行通信。
发布于 2019-10-07 10:35:08
使用共享内存进行通信的问题之一是,与调度程序没有任何协作。具体来说,任务无法阻塞(所以它不用CPU时间),直到数据到达/更改,然后在数据到达/更改时解除阻塞。
对于用户空间和内核之间的通信,您也会遇到同样的问题。例如,用户空间代码修改“与内核共享”内存中的数据,内核不知道这是否/何时发生;因此(为了避免内核浪费CPU时间经常轮询共享内存),用户空间代码必须使用一个普通的内核调用来表示“嘿,现在看看共享内存!”,但是如果您无论如何都在使用一个普通的内核调用,那么您可以传递一个指向数据的指针,而不用使用共享内存。
使用共享内存进行通信的另一个问题是安全风险。具体来说,任务可以看到数据到达/更改,验证新数据以确保其可接受,然后恶意攻击者可以在数据验证后更改数据,然后任务可以对“验证”数据进行操作。一个非常简单的例子是类似于"
if(new_value_in_shared_memory < MAX_VALUE) { myPrivateArray[new_value_in_shared_memory]++;
“的东西(恶意攻击者在检查
new_value_in_shared_memory
之后会改变它,将任务欺骗为修改它不应该修改的东西)。对于相互信任的任务(例如,与
fork()
本身通信的进程),这根本不是问题;当参与者不信任对方(例如内核不信任用户空间代码)时,这是一个很大的痛苦(非常容易出错和被典当)。防范这种攻击的最简单方法是将数据从共享内存复制到私有缓冲区,然后验证它(知道攻击者不可能修改副本),然后对副本中的数据进行操作。这种复制增加了开销,并且破坏了共享内存的任何性能优势。
对于“与内核进行用户空间通信”的情况,有几种可能的选择--内核可以在“验证然后使用”阶段挂起可以访问共享内存的所有线程(这将是性能灾难,特别是对于多CPU系统);内核可以在“验证然后使用”阶段(特别是对于多CPU系统)执行虚拟内存管理技巧(例如,如果用户空间试图修改它的话,将底层页面设置为“页面错误”)(这将是性能灾难,特别是对于多CPU系统)。
请注意,对于“内核调用接受指向用户空间的数据的指针”和“内核调用依赖于用户空间任务堆栈中的数据”,同样的“经过验证后修改”的安全风险也会发生。但是,对于这两种情况(不涉及共享内存,但确实涉及“内核访问任务的正常内存”),内核通常不会实际访问和只传输数据。例如,对于一个
write()
,内核可能将数据转发到文件系统代码(而不接触数据本身),后者可能将数据转发到存储设备驱动程序(而不接触数据本身),后者可能将数据传输到硬盘驱动器(而不触及数据本身)。
发布于 2019-10-07 10:34:08
共享内存和内核线程是正交的。内核始终可以访问任何进程的整个地址空间。如果需要的话,内核可以从syscall、从中断处理程序、计时器回调或内核线程访问它。
https://stackoverflow.com/questions/58265439
复制相似问题
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2024 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287