新手上路,希望得到一些指点!先谢谢各位大哥了
“设备支持 DMA”这句话,我从如下两个方面理解:
想知道以上理解是否有误?且也在探索该如何在一个 host 上以扫描的形式判断有哪些设备具有 DMA 能力...希望获取一些建议,或者能提供一些可以努力的方向!
1
ins0mn1a OP 补充一点更具体的信息:是在做移动端关于 DMA 的研究,所以设备初始化是基于设备树的。
通过临时的相关 kernel 源码阅读,目前我有如下认识: 认为设备树无法提供完整的 DMA 信息,部分设备树 dts 中不做 DMA 配置的节点,也会执行 dma 相关的 configure ,例如,在基于设备树的情况下,最终都是调用[of_dma_configure()]( https://elixir.bootlin.com/linux/v5.6.5/source/drivers/of/device.c#L75),该函数注释中说明,由于遗留问题,即便不在设备树中设置 dma 相关的信息,也会为其做一些默认的赋值; 且该函数的调用是由当前 dev 对应的 bus 决定的,即一个在设备树中没有设置 dma 相关选项的设备会因为其挂接的总线支持 DMA 而在 matching 阶段执行相关的 DMA 初始化,并被赋上默认值,而导致该设备在总线侧和驱动侧都是完成了对 DMA 支持的,那么此时这个设备是拥有 DMA 能力的吗? |
2
yuguorui96 2022-05-10 23:58:15 +08:00
设备支持不支持 DMA 和驱动没有必然联系。
一个设备有 DMA 控制器,能朝系统总线上写 DMA 相关的消息就可以进行 DMA 了(假设我不关心会不会把系统写挂)。以 PIC 为例,DMA 的过程实际就是写 TLP 包的过程,然后就可以通过 PCI 的路由逻辑路由到 DIMM 里了,这个过程和任何驱动有关吗? |
3
yuguorui96 2022-05-11 00:02:02 +08:00
说的更明白点,如果我是一个已经挂载在总线上的恶意设备,如果我不主动暴露 DMA 能力,没啥好方法探测。
如果你的假设是设备都是诚实的,倒是可以翻翻驱动,看看驱动分配时有没有用 DMA 相关的内存分配 API ,但是这个都只是启发式的。 |
4
ins0mn1a OP @yuguorui96 谢谢你的回复!现阶段的想法也就只是看看 dma api 了...另外还想再探讨一下关于恶意设备的问题;
由这个恶意设备的例子展开去,现阶段对于类似的 DMA attack 的防护大多基于 IOMMU 机制,而一个设备与 IOMMU 进行绑定,即“使用 IOMMU”来限制 DMA 攻击的情景,kernel boot time 是在板上设备在与驱动进行绑定的 probe 阶段,为设备分配置 IOMMU 。据此我产生的理解就是,一个设备想接上 IOMMU 需要经过驱动绑定的 probe 阶段(?不一定对,源码是: https://elixir.bootlin.com/linux/v5.17.6/source/drivers/base/dd.c#L871 ) 再说回你的例子,如果你说的恶意设备是一个热插拔的具有 DMA 能力的非板上的外部设备,成功挂载且无法匹配任何总线上的驱动,此时程序流不会走到 probe 分支,是否也就意味着该设备不会受到 IOMMU 的保护呢? |
5
yuguorui96 2022-05-11 10:14:23 +08:00
@ins0mn1a 你这里 post 出来的代码我还没看,但是大体上的逻辑是:
1. firmware 需要在启动时默认启用 IOMMU remapping ,然后后续的 DMA 请求就被默认禁止了; 2. 后面 firmware/OS 就可以根据需求更新 IOMMU 的 second-level page table 以允许 /吊销设备的 DMA 访问能力。 是否也就意味着该设备不会受到 IOMMU 的保护呢? ==================================== 否 这里的细节很多,可以参考: https://www.intel.com/content/dam/develop/external/us/en/documents/intel-whitepaper-using-iommu-for-dma-protection-in-uefi-820238.pdf |
6
ins0mn1a OP @yuguorui96 也就是说,在 IOMMU 被配置的 OS 上,普通的 DMA 请求会被禁止,只有使用 IOMMU 的 DMA 设备能够发起 DMA 访问是吗?非常感谢,会去读一下启动时关于 IOMMU 的配置代码以及阅读一下这篇文章的。
|
7
ins0mn1a OP @yuguorui96 先介绍一篇 gp0 的文章: https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html
其中一种 get root shell 的方式,是通过完全控制的 wifi SoC 使用 DMA 来完成攻击的,这个 wifi SoC 没有与 IOMMU 形成绑定,作者没有深究根本原因是主 SoC (骁龙 810 )没有硬件 IOMMU 还是当时的安卓系统没有默认启用 IOMMU ,又提到在该 wifi SoC 的 documentation 中,没有关于 iommu 的 dtbinding 相关的介绍; 查了下骁龙 810 ,其实是有 IOMMU 的,再结合设备树没有做 binding ,我就想当然的认为系统可能是支持 IOMMU 的,但是这个 DMA 设备由于缺少与 IOMMU 的绑定,而没有受到 IOMMU 的保护,这点逻辑在 kernel 中 dma api 的具体实现中也有体现,针对绑定了 iommu 的设备,会走一个 iommu 相关的 dma 分支,没有绑定则会走另一个分支。 因此我会去确认一下,这个案例中的系统版本究竟是否支持 IOMMU 。 |