Re: [PATCH 1/1] swiotlb: fix out-of-bounds TLB allocations with CONFIG_SWIOTLB_DYNAMIC

From: Petr Tesařík
Date: Wed Nov 08 2023 - 07:21:28 EST


On Wed, 8 Nov 2023 12:12:49 +0100
Petr Tesarik <petrtesarik@xxxxxxxxxxxxxxx> wrote:

> From: Petr Tesarik <petr.tesarik1@xxxxxxxxxxxxxxxxxxx>
>
> Limit the free list length to the size of the IO TLB. Transient pool can be
> smaller than IO_TLB_SEGSIZE, but the free list is initialized with the
> assumption that the total number of slots is a multiple of IO_TLB_SEGSIZE.
> As a result, swiotlb_area_find_slots() may allocate slots past the end of
> a transient IO TLB buffer.

Just to make it clear, this patch addresses only the memory corruption
reported by Niklas, without addressing the underlying issues. Where
corruption happened before, allocations will fail with this patch.

I am still looking into improving the allocation strategy itself.

Petr T

> Reported-by: Niklas Schnelle <schnelle@xxxxxxxxxxxxx>
> Closes: https://lore.kernel.org/linux-iommu/104a8c8fedffd1ff8a2890983e2ec1c26bff6810.camel@xxxxxxxxxxxxx/
> Fixes: 79636caad361 ("swiotlb: if swiotlb is full, fall back to a transient memory pool")
> Cc: Halil Pasic <pasic@xxxxxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Petr Tesarik <petr.tesarik1@xxxxxxxxxxxxxxxxxxx>
> ---
> kernel/dma/swiotlb.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 26202274784f..ec82524ba902 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -283,7 +283,8 @@ static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> }
>
> for (i = 0; i < mem->nslabs; i++) {
> - mem->slots[i].list = IO_TLB_SEGSIZE - io_tlb_offset(i);
> + mem->slots[i].list = min(IO_TLB_SEGSIZE - io_tlb_offset(i),
> + mem->nslabs - i);
> mem->slots[i].orig_addr = INVALID_PHYS_ADDR;
> mem->slots[i].alloc_size = 0;
> }