Why does a device need a page table for DMA? And how can a DMA attack occur on memory allocated by the OS?
I am studying the interaction between IOMMU and the operating system, but I have encountered a few questions.
Q1. When a device performs DMA, it accesses main memory using an IOVA allocated by the OS. According to research papers, it is stated that the DMA mapping is unmapped after each DMA transfer. This leads me to question the following: if every DMA mapping is unmapped after use, why does the OS need to maintain an IO page table for each device? To address this, I have come up with a few hypotheses:
A single DMA transfer does not consist of just one memory access but involves multiple accesses. As a result, a single DMA transfer requires multiple DMA mappings and uses the IOVA multiple times, thus necessitating the existence of a page table.
Based on the Linux dma_api documentation, there are two types of DMA mappings. The first is consistent mapping, which is used in ring buffers. The second is streaming mapping, which is used for network buffers in NICs. Since the ring buffer is a persistent buffer, it requires a page table. Therefore, page tables are only necessary for ring buffers.
If the deferred method is used, unmapping is not performed for every DMA. Hence, the page table design assumes the deferred method from the beginning.
According to the Linux documentation, even in the streaming mapping method, buffers can be reused using dma_sync. Although I’m not sure under what circumstances dma_sync is used to reuse a buffer, the page table is maintained for cases where buffer reuse is needed
The four hypotheses I presented don’t seem entirely convincing. Since the DMA mapping is unmapped after each DMA transfer, it appears there would be no need to access the same buffer again. So, why does the OS still need to maintain a page table?
Q2. I understand that one reason for unmapping DMA mappings after each transfer is to prevent rogue devices from maliciously accessing previously allocated buffers, potentially compromising the OS or overwriting data.
However, let’s consider a scenario where the OS allocates a DMA buffer for the NIC to receive data via DMA. Since the OS has already designated this memory as a DMA buffer, there seems to be no reason for the OS to write anything else to this memory. Given this, how could a device use this buffer to perform a DMA attack?
A DMA attack typically involves a device either (1) writing unauthorized data to overwrite sensitive areas of main memory, or (2) reading sensitive OS data without permission. But in this case, neither scenario seems plausible. Could someone clarify how a DMA attack could occur in this context?
Q3. Why is the buffer used to receive DMA in NICs mapped using the streaming mapping method?
I understand that using consistent mapping could be wasteful in this case, especially because network traffic is highly dynamic. However, even with streaming mapping, when the network traffic increases, new buffers still need to be allocated, just as with consistent mapping.
Moreover, if buffers are pre-allocated using consistent mapping to accommodate a reasonable amount of network traffic, it would eliminate the need to unmap the DMA after every transfer, remove page table entries, and deallocate buffer memory. Wouldn't this approach allow for a slight memory overhead in exchange for significantly improved performance?
For reference, the papers I’ve read so far are:
"Utilizing the IOMMU Scalably" "Efficient Intra-Operating System Protection Against Harmful DMAs" "Linux document DMA_API"
help me plz !
|