From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Pavel Begunkov <asml.silence@gmail.com>,
Jens Axboe <axboe@kernel.dk>, Sasha Levin <sashal@kernel.org>,
io-uring@vger.kernel.org
Subject: [PATCH AUTOSEL 6.17] io_uring/zcrx: check all niovs filled with dma addresses
Date: Thu, 9 Oct 2025 11:54:47 -0400 [thread overview]
Message-ID: <20251009155752.773732-21-sashal@kernel.org> (raw)
In-Reply-To: <20251009155752.773732-1-sashal@kernel.org>
From: Pavel Begunkov <asml.silence@gmail.com>
[ Upstream commit d7ae46b454eb05e3df0d46c2ac9c61416a4d9057 ]
Add a warning if io_populate_area_dma() can't fill in all net_iovs, it
should never happen.
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
YES
- What it changes
- Adds a post-loop invariant check in `io_populate_area_dma()` to
ensure every `net_iov` in the area got a valid DMA address. If not,
it emits a one-time warning and fails the mapping with `-EFAULT`:
- New logic: “if not all niovs filled → WARN_ON_ONCE + return
-EFAULT”
- Before: the function always returned 0 even if it didn’t populate
all niovs.
- This is a small, localized change to `io_uring/zcrx.c` that does not
alter APIs or structures and only affects the zcrx receive path.
- Why it matters (bug/risk being fixed)
- Today, `io_populate_area_dma()` returns success unconditionally
after walking the SG table, even if fewer DMA addresses were written
than `area->nia.num_niovs`. See unconditional return in
`io_uring/zcrx.c:78`.
- On success, `io_zcrx_map_area()` marks the area as mapped (sets
`area->is_mapped = true`), which enables the page_pool memory
provider to start using these entries, assuming per-`net_iov` DMA
addresses are valid:
- `io_uring/zcrx.c:277` and `io_uring/zcrx.c:290-293`
- DMA addresses are later consumed in sync paths (e.g.,
`io_zcrx_sync_for_device()`), which fetches them via
`page_pool_get_dma_addr_netmem()`: `io_uring/zcrx.c:304-306`.
- If some `net_iov`s remained uninitialized (DMA address 0 or stale),
the NIC could be programmed with an invalid DMA address. That is a
correctness and potential security issue (device DMA to the wrong
address). The new check prevents entering that state by failing
early instead of silently accepting a partially-initialized mapping.
- Context and call sites
- `io_populate_area_dma()` is used by both umem and dmabuf mappings:
- dmabuf mapping calls into `io_populate_area_dma()` at
`io_uring/zcrx.c:159-161`. Upstream already validates the SG total
size matches the area length (`io_uring/zcrx.c:139-146`), but the
new invariant check still hardens against any mismatch in the
subsequent per-page DMA population loop.
- umem mapping path invokes it after `dma_map_sgtable()`:
`io_uring/zcrx.c:270-275`.
- On error, both paths propagate the error, and `io_zcrx_map_area()`
will not set `area->is_mapped = true` (`io_uring/zcrx.c:290-293`),
preventing the page_pool consumer from using invalid entries. This
aligns with other existing error checks in the function (e.g.,
`net_mp_niov_set_dma_addr()` failure returns `-EFAULT` already at
`io_uring/zcrx.c:71-72`).
- Stable backport criteria assessment
- Fixes a real bug class (silent partial initialization of DMA
addresses) that can lead to invalid device DMA targets. Even if the
author says it “should never happen,” enforcing the invariant
eliminates a dangerous failure mode rather than allowing undefined
behavior.
- Change is small and tightly scoped to zcrx; it adds one WARN_ON_ONCE
and a conditional `-EFAULT` return. No interface, ABI, or
architectural changes.
- Callers already handle negative returns and will abort mapping
cleanly, so regression risk is minimal and clearly bounded to
failing early when an invariant is violated.
- No new features; pure correctness/hardening.
- Touches io_uring zcrx, not core scheduling or memory subsystems;
impact is contained.
- Additional code references supporting the assessment
- Unconditional success today: `io_uring/zcrx.c:52-79` (function body,
unconditional `return 0` at `io_uring/zcrx.c:78`).
- Caller sets `is_mapped` only on success: `io_uring/zcrx.c:277-293`.
- DMA address is used later for device sync:
`io_uring/zcrx.c:304-306`.
- dmabuf SG size checked already: `io_uring/zcrx.c:139-146`.
Conclusion: This is a low-risk, correctness hardening that prevents a
silent and potentially serious failure mode. It satisfies stable rules
for a minimal, contained bugfix. Backport to stable trees that include
`io_uring/zcrx` and `io_populate_area_dma()` is advisable.
io_uring/zcrx.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index e5ff49f3425e0..39d1ef52a57b1 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -75,6 +75,9 @@ static int io_populate_area_dma(struct io_zcrx_ifq *ifq,
niov_idx++;
}
}
+
+ if (WARN_ON_ONCE(niov_idx != area->nia.num_niovs))
+ return -EFAULT;
return 0;
}
--
2.51.0
next parent reply other threads:[~2025-10-09 15:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251009155752.773732-1-sashal@kernel.org>
2025-10-09 15:54 ` Sasha Levin [this message]
2025-10-09 15:55 ` [PATCH AUTOSEL 6.17-6.12] io_uring/zctx: check chained notif contexts Sasha Levin
2025-10-09 15:55 ` [PATCH AUTOSEL 6.17-6.16] io_uring/rsrc: respect submitter_task in io_register_clone_buffers() Sasha Levin
2025-10-09 15:55 ` [PATCH AUTOSEL 6.17-6.16] io_uring/zcrx: account niov arrays to cgroup Sasha Levin
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=20251009155752.773732-21-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=asml.silence@gmail.com \
--cc=axboe@kernel.dk \
--cc=io-uring@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox