lkml.org 
[lkml]   [2022]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH 05/10] dmapool: debug: prevent endless loop in case of corruption
    From
    Prevent a possible endless loop with DMAPOOL_DEBUG enabled if a buggy
    driver corrupts DMA pool memory.

    Signed-off-by: Tony Battersby <tonyb@cybernetics.com>
    ---
    mm/dmapool.c | 37 ++++++++++++++++++++++++++++++-------
    1 file changed, 30 insertions(+), 7 deletions(-)

    diff --git a/mm/dmapool.c b/mm/dmapool.c
    index 9e30f4425dea..7a9161d4f7a6 100644
    --- a/mm/dmapool.c
    +++ b/mm/dmapool.c
    @@ -426,16 +426,39 @@ void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
    }
    {
    unsigned int chain = page->offset;
    + unsigned int free_blks = 0;
    +
    while (chain < pool->allocation) {
    - if (chain != offset) {
    - chain = *(int *)(page->vaddr + chain);
    - continue;
    + if (unlikely(chain == offset)) {
    + spin_unlock_irqrestore(&pool->lock, flags);
    + dev_err(pool->dev,
    + "%s %s, dma %pad already free\n",
    + __func__, pool->name, &dma);
    + return;
    }
    - spin_unlock_irqrestore(&pool->lock, flags);
    - dev_err(pool->dev, "%s %s, dma %pad already free\n",
    - __func__, pool->name, &dma);
    - return;
    +
    + /*
    + * A buggy driver could corrupt the freelist by
    + * use-after-free, buffer overflow, etc. Besides
    + * checking for corruption, this also prevents an
    + * endless loop in case corruption causes a circular
    + * loop in the freelist.
    + */
    + if (unlikely(++free_blks + page->in_use >
    + pool->blks_per_alloc)) {
    + freelist_corrupt:
    + spin_unlock_irqrestore(&pool->lock, flags);
    + dev_err(pool->dev,
    + "%s %s, freelist corrupted\n",
    + __func__, pool->name);
    + return;
    + }
    +
    + chain = *(int *)(page->vaddr + chain);
    }
    + if (unlikely(free_blks + page->in_use !=
    + pool->blks_per_alloc))
    + goto freelist_corrupt;
    }
    memset(vaddr, POOL_POISON_FREED, pool->size);
    #endif
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-05-31 20:20    [W:4.124 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site