From: Leon Romanovsky <leon@kernel.org>
To: David Hu <xuehaohu@google.com>
Cc: "Sumit Semwal" <sumit.semwal@linaro.org>,
"Christian König" <christian.koenig@amd.com>,
"Jason Gunthorpe" <jgg@ziepe.ca>,
"Nicolin Chen" <nicolinc@nvidia.com>,
"Kevin Tian" <kevin.tian@intel.com>,
"Ankit Agrawal" <ankita@nvidia.com>,
"Alex Williamson" <alex@shazbot.org>,
linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org,
linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org,
iommu@lists.linux.dev, jmoroni@google.com, praan@google.com,
stable@vger.kernel.org
Subject: Re: [PATCH v5] dma-buf: Fix silent overflow for phys vec to sgt
Date: Thu, 4 Jun 2026 12:43:44 +0300 [thread overview]
Message-ID: <20260604094344.GB245424@unreal> (raw)
In-Reply-To: <20260601200012.3872274-1-xuehaohu@google.com>
On Mon, Jun 01, 2026 at 08:00:12PM +0000, David Hu wrote:
> In case MMIO size is bigger than 4G and peer2peer DMA goes
> through host bridge, we trigger a code path that assigns the
> total linked IOVA (which is greater than 4G) to mapped_len.
>
> Previously, `mapped_len` was declared as 32-bit `unsigned int`.
> When accumulating `size_t` lengths, this leads to a silent wrap-around.
> This truncation causes truncated lengths to be passed to functions
> like `fill_sg_entry()`.
>
> Fix this by changing `mapped_len` to `size_t` (64-bit). While
> at it, fix similar potential overflow issues in `calc_sg_nents`
> by using `size_t` for `nents` and checking against `UINT_MAX`
> and using `unsigned int` for the loop iterator in `fill_sg_entry`
> to match.
>
> Fixes: 3aa31a8bb11e ("dma-buf: provide phys_vec to scatter-gather mapping routine")
> Cc: stable@vger.kernel.org
> Cc: iommu@lists.linux.dev
> Reviewed-by: Pranjal Shrivastava <praan@google.com>
> Signed-off-by: David Hu <xuehaohu@google.com>
> ---
> Changes in v5:
> - Removed WARN_ON_ONCE from calc_sg_nents() to avoid log noise (Jason).
> - Added explicit check for `!nents` in dma_buf_phys_vec_to_sgt() to
> cleanly return -EINVAL on overflow (Jason).
>
> Changes in v4:
> - Added WARN_ON_ONCE() to the nents overflow check to prevent silent
> failures (Claude Bot).
>
> Changes in v3:
> - Removed leftover sentence fragment from the commit message.
> - Kept `nents = 0` initialization (previously stated as removed in the
> v2 changelog) as it is strictly required for the `+=` accumulation
> loop in `calc_sg_nents()`.
>
> Changes in v2:
> - Fixed 'IVOA' -> 'IOVA' typo and expanded commit message (Claude Bot).
> - Added Reverse Xmas tree formatting (Pranjal).
> - Folded in extra bounds checking for calc_sg_nents() (Pranjal).
> - Folded in type consistency fix for fill_sg_entry() (Pranjal).
>
> drivers/dma-buf/dma-buf-mapping.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
> index 794acff2546a..607b7998463d 100644
> --- a/drivers/dma-buf/dma-buf-mapping.c
> +++ b/drivers/dma-buf/dma-buf-mapping.c
> @@ -10,7 +10,7 @@ static struct scatterlist *fill_sg_entry(struct scatterlist *sgl, size_t length,
> dma_addr_t addr)
> {
> unsigned int len, nents;
> - int i;
> + unsigned int i;
>
> nents = DIV_ROUND_UP(length, UINT_MAX);
> for (i = 0; i < nents; i++) {
> @@ -36,7 +36,7 @@ static unsigned int calc_sg_nents(struct dma_iova_state *state,
> struct phys_vec *phys_vec, size_t nr_ranges,
> size_t size)
> {
> - unsigned int nents = 0;
> + size_t nents = 0;
> size_t i;
>
> if (!state || !dma_use_iova(state)) {
> @@ -51,6 +51,9 @@ static unsigned int calc_sg_nents(struct dma_iova_state *state,
> nents = DIV_ROUND_UP(size, UINT_MAX);
> }
>
> + if (nents > UINT_MAX)
I would suggest to use check_add_overflow() while calculating nents
instead of this check.
> + return 0;
> +
> return nents;
> }
>
> @@ -95,9 +98,10 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
> size_t nr_ranges, size_t size,
> enum dma_data_direction dir)
> {
> - unsigned int nents, mapped_len = 0;
> struct dma_buf_dma *dma;
> struct scatterlist *sgl;
> + size_t mapped_len = 0;
> + unsigned int nents;
> dma_addr_t addr;
> size_t i;
> int ret;
> @@ -133,6 +137,11 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
> }
>
> nents = calc_sg_nents(dma->state, phys_vec, nr_ranges, size);
> + if (!nents) {
> + ret = -EINVAL;
> + goto err_free_state;
> + }
Technically, this hunk is not necessary, since sg_alloc_table() will
return -EINVAL when nents == 0. At least, that is the behavior I relied on.
Thanks
> +
> ret = sg_alloc_table(&dma->sgt, nents, GFP_KERNEL | __GFP_ZERO);
> if (ret)
> goto err_free_state;
> --
> 2.54.0.929.g9b7fa37559-goog
>
next prev parent reply other threads:[~2026-06-04 9:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-01 20:00 [PATCH v5] dma-buf: Fix silent overflow for phys vec to sgt David Hu
2026-06-01 20:13 ` sashiko-bot
2026-06-03 7:04 ` Tian, Kevin
2026-06-04 9:43 ` Leon Romanovsky [this message]
2026-06-04 19:36 ` David Hu
2026-06-07 8:02 ` Leon Romanovsky
2026-06-08 18:54 ` David Hu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260604094344.GB245424@unreal \
--to=leon@kernel.org \
--cc=alex@shazbot.org \
--cc=ankita@nvidia.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@ziepe.ca \
--cc=jmoroni@google.com \
--cc=kevin.tian@intel.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=praan@google.com \
--cc=stable@vger.kernel.org \
--cc=sumit.semwal@linaro.org \
--cc=xuehaohu@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.