Re: [PATCH v3 2/5] iommu/dma: Catch scatterlist length overflows

Krzysztof Karas <[email protected]>
Newsgroups org.freedesktop.lists.intel-gfx,dev.linux.lists.iommu,org.freedesktop.lists.dri-devel
Message-ID <4nqoxr2shgvpd6ury7ko5amnkap6nimds353ahho2jggdkk2f3@uniz2nufegkm>
Hi Robin,

On 2026-07-16 at 14:48:25 +0100, Robin Murphy wrote:
> On 13/07/2026 10:58 am, Krzysztof Karas wrote:
> > It is possible, when a very large mapping uses only one
> > 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 scatterlist
> > length field.
> > 
> > Fixes: 809eac54cdd6 ("iommu/dma: Implement scatterlist segment merging")
> > Signed-off-by: Krzysztof Karas <[email protected]>
> > ---
> > v3:
> >   * Used check_add_overflow suggested by Jason.
> > 
> > I decided not to include previous r-bs due to the change in the
> > core of this patch: overflows_type -> check_add_overflow and I
> > obvserved some folks have heavy preference for one or the other.
> > 
> >   drivers/iommu/dma-iommu.c | 13 ++++++++++++-
> >   1 file changed, 12 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
> > index 381b60d9e7ce..1a36fd9bf10b 100644
> > --- a/drivers/iommu/dma-iommu.c
> > +++ b/drivers/iommu/dma-iommu.c
> > @@ -1493,7 +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).
> >   		 */
> 
> Sorry to be a pain,
Don't be! I'm glad you got some time to look at this again and
being a pain is what gives us quality code.

> but since we *have* now spent the time reasoning through
> the details, for completeness I think it would be worth also explicitly
> checking "s_length & UINT_MAX != 0" (or equivalent) after the the prior
> iova_align() - since that's only rounding up an unsigned int value to a
> power of 2 it can't arbitrarily overflow like the addition below, but it
> could still wrap to zero in the assignment to s->length, or indeed in the
> size_t itself on 32-bit.
> 
> >   		if (pad_len && pad_len < s_length - 1) {
> > -			prev->length += pad_len;
> > +			unsigned int new_pad_len;
> 
> Super-nit: "pad_len" is the amount of potential padding from the end of the
> previous segment up to the next segment boundary; the value we're
> calculating here is the updated *total* segment length, so "new_prev_len"
> would be more accurate and a bit clearer - the logic here is fiddly enough
> as it is, so every little helps :)
Both suggestions sound reasonable, I'll include them in the next
version then.
> 
> With those tweaks (since it sounds like there's still another respin or two
> to go for the rest of the series anyway),
> 
> Reviewed-by: Robin Murphy <[email protected]>
Thanks!

-- 
Best Regards,
Krzysztof
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.