lkml.org 
[lkml]   [2022]   [Mar]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [REGRESSION] Recent swiotlb DMA_FROM_DEVICE fixes break ath9k-based AP
    From
    On 2022-03-23 19:16, Linus Torvalds wrote:
    > On Wed, Mar 23, 2022 at 12:06 PM Robin Murphy <robin.murphy@arm.com> wrote:
    >>
    >> On 2022-03-23 17:27, Linus Torvalds wrote:
    >>>
    >>> I'm assuming that the ath9k issue is that it gives DMA mapping a big
    >>> enough area to handle any possible packet size, and just expects -
    >>> quite reasonably - smaller packets to only fill the part they need.
    >>>
    >>> Which that "info leak" patch obviously breaks entirely.
    >>
    >> Except that's the exact case which the new patch is addressing
    >
    > Not "addressing". Breaking.
    >
    > Which is why it will almost certainly get reverted.
    >
    > Not doing DMA to the whole area seems to be quite the sane thing to do
    > for things like network packets, and overwriting the part that didn't
    > get DMA'd with zeroes seems to be exactly the wrong thing here.
    >
    > So the SG_IO - and other random untrusted block command sources - data
    > leak will almost certainly have to be addressed differently. Possibly
    > by simply allocating the area with GFP_ZERO to begin with.

    Er, the point of the block layer case is that whole area *is* zeroed to
    begin with, and a latent memory corruption problem in SWIOTLB itself
    replaces those zeros with random other kernel data unexpectedly. Let me
    try illustrating some sequences for clarity...

    Expected behaviour/without SWIOTLB:
    Memory
    ---------------------------------------------------
    start 12345678
    dma_map(DMA_FROM_DEVICE) no-op
    device writes partial data 12ABC678 <- ABC
    dma_unmap(DMA_FROM_DEVICE) 12ABC678


    SWIOTLB previously:
    Memory Bounce buffer
    ---------------------------------------------------
    start 12345678 xxxxxxxx
    dma_map(DMA_FROM_DEVICE) no-op
    device writes partial data 12345678 xxABCxxx <- ABC
    dma_unmap(DMA_FROM_DEVICE) xxABCxxx <- xxABCxxx


    SWIOTLB Now:
    Memory Bounce buffer
    ---------------------------------------------------
    start 12345678 xxxxxxxx
    dma_map(DMA_FROM_DEVICE) 12345678 -> 12345678
    device writes partial data 12345678 12ABC678 <- ABC
    dma_unmap(DMA_FROM_DEVICE) 12ABC678 <- 12ABC678


    Now, sure we can prevent any actual information leakage by initialising
    the bounce buffer slot with zeros, but then we're just corrupting the
    not-written-to parts of the mapping with zeros instead of anyone else's
    old data. That's still fundamentally not OK. The only thing SWIOTLB can
    do to be correct is treat DMA_FROM_DEVICE as a read-modify-write of the
    entire mapping, because it has no way to know how much of it is actually
    going to be modified.

    I'll admit I still never quite grasped the reason for also adding the
    override to swiotlb_sync_single_for_device() in aa6f8dcbab47, but I
    think by that point we were increasingly tired and confused and starting
    to second-guess ourselves (well, I was, at least). I don't think it's
    wrong per se, but as I said I do think it can bite anyone who's been
    doing dma_sync_*() wrong but getting away with it until now. If
    ddbd89deb7d3 alone turns out to work OK then I'd be inclined to try a
    partial revert of just that one hunk.

    Thanks,
    Robin.

    \
     
     \ /
      Last update: 2022-03-23 21:55    [W:9.054 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site