On Wed, Jul 01, 2026 at 10:44:37AM +0000, Krzysztof Karas wrote:
> It is possible, when a very large mapping uses a single
> scatterlist, that padding overflows scatterlist's length field.
> This results in:
> 1) silently wrapping the value
> 2) smaller than desired mappings produced by iommu_map_sg
> 3) leaving mapped bytes in memory (no iommu_unmap)
>
> Address this issue by adding overflow detection for previous
> scatterlist length field.
Urk, this is unfortunate, it means we cannot map certain kinds of
scatterlists? Meaning there is a condition that makes a scatterlist
ill formed?
This seems like something that needs to be more clearly documented and
we need to ensure at least the common scatterlist builders don't hit
it..
> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> index 9abaec0703ef..c403057577df 100644
> --- a/drivers/iommu/dma-iommu.c
> +++ b/drivers/iommu/dma-iommu.c
> @@ -1493,8 +1493,18 @@ int iommu_dma_map_sg(struct device *dev, struct
> scatterlist *sg, int nents,
> * time through here (i.e. before it has a meaningful value).
> */
> if (pad_len && pad_len < s_length - 1) {
> - prev->length += pad_len;
> - iova_len += pad_len;
> + if (overflows_type(prev->length + pad_len,
> prev->length)) {
> + /*
> + * For large mappings spanning multiple GBs we
> + * may not be able to fit all needed padding
> into
> + * sg->length.
> + */
> + ret = -EOVERFLOW;
> + goto out_restore_sg;
> + } else {
> + prev->length += pad_len;
> + iova_len += pad_len;
> + }
It is better to use
check_add_overflow(prev->length, pad_len, &prev->length)
instead of overflows_type()..
Jason