* [PATCH net 1/1] net: devmem: prevent net-iov / page mixing
@ 2026-07-22 10:58 Pavel Begunkov
2026-07-22 17:59 ` Bobby Eshleman
2026-07-22 19:49 ` Mina Almasry
0 siblings, 2 replies; 7+ messages in thread
From: Pavel Begunkov @ 2026-07-22 10:58 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, netdev
Cc: asml.silence, Mina Almasry
We should either have net_iov or page backed frags in a single skb,
otherwise it blows up down the stack. Don't allow mixing in
zerocopy_fill_skb_from_devmem().
Fixes: bd61848900bff ("net: devmem: Implement TX path")
Cc: stable@vger.kernel.org
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
net/core/datagram.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/core/datagram.c b/net/core/datagram.c
index c285c6465923..35febc1c25fa 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -712,6 +712,9 @@ zerocopy_fill_skb_from_devmem(struct sk_buff *skb, struct iov_iter *from,
size_t virt_addr, size, off;
struct net_iov *niov;
+ if (i && skb_frags_readable(skb))
+ return -EEXIST;
+
/* Devmem filling works by taking an IOVEC from the user where the
* iov_addrs are interpreted as an offset in bytes into the dma-buf to
* send from. We do not support other iter types.
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-22 10:58 [PATCH net 1/1] net: devmem: prevent net-iov / page mixing Pavel Begunkov @ 2026-07-22 17:59 ` Bobby Eshleman 2026-07-22 18:58 ` Pavel Begunkov 2026-07-22 19:49 ` Mina Almasry 1 sibling, 1 reply; 7+ messages in thread From: Bobby Eshleman @ 2026-07-22 17:59 UTC (permalink / raw) To: Pavel Begunkov Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, Mina Almasry On Wed, Jul 22, 2026 at 11:58:46AM +0100, Pavel Begunkov wrote: > We should either have net_iov or page backed frags in a single skb, > otherwise it blows up down the stack. Don't allow mixing in > zerocopy_fill_skb_from_devmem(). > > Fixes: bd61848900bff ("net: devmem: Implement TX path") > Cc: stable@vger.kernel.org > Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> > --- > net/core/datagram.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/net/core/datagram.c b/net/core/datagram.c > index c285c6465923..35febc1c25fa 100644 > --- a/net/core/datagram.c > +++ b/net/core/datagram.c > @@ -712,6 +712,9 @@ zerocopy_fill_skb_from_devmem(struct sk_buff *skb, struct iov_iter *from, > size_t virt_addr, size, off; > struct net_iov *niov; > > + if (i && skb_frags_readable(skb)) > + return -EEXIST; Are we trying to hit the -EEXIST handler in tcp_sendmsg_locked() so that we start a new skb? If so, I think we might need to plumb this -EEXIST case through skb_zerocopy_iter_stream() too? Best, Bobby ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-22 17:59 ` Bobby Eshleman @ 2026-07-22 18:58 ` Pavel Begunkov 0 siblings, 0 replies; 7+ messages in thread From: Pavel Begunkov @ 2026-07-22 18:58 UTC (permalink / raw) To: Bobby Eshleman Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, Mina Almasry On 7/22/26 18:59, Bobby Eshleman wrote: > On Wed, Jul 22, 2026 at 11:58:46AM +0100, Pavel Begunkov wrote: >> We should either have net_iov or page backed frags in a single skb, >> otherwise it blows up down the stack. Don't allow mixing in >> zerocopy_fill_skb_from_devmem(). >> >> Fixes: bd61848900bff ("net: devmem: Implement TX path") >> Cc: stable@vger.kernel.org >> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> >> --- >> net/core/datagram.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/net/core/datagram.c b/net/core/datagram.c >> index c285c6465923..35febc1c25fa 100644 >> --- a/net/core/datagram.c >> +++ b/net/core/datagram.c >> @@ -712,6 +712,9 @@ zerocopy_fill_skb_from_devmem(struct sk_buff *skb, struct iov_iter *from, >> size_t virt_addr, size, off; >> struct net_iov *niov; >> >> + if (i && skb_frags_readable(skb)) >> + return -EEXIST; > > Are we trying to hit the -EEXIST handler in tcp_sendmsg_locked() so that > we start a new skb? If so, I think we might need to plumb this -EEXIST > case through skb_zerocopy_iter_stream() too? Easier to EFAULT. It'd more consistent, and I don't care how tcp takes it specifically. -- Pavel Begunkov ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-22 10:58 [PATCH net 1/1] net: devmem: prevent net-iov / page mixing Pavel Begunkov 2026-07-22 17:59 ` Bobby Eshleman @ 2026-07-22 19:49 ` Mina Almasry 2026-07-22 20:20 ` Pavel Begunkov 2026-07-23 17:24 ` Bobby Eshleman 1 sibling, 2 replies; 7+ messages in thread From: Mina Almasry @ 2026-07-22 19:49 UTC (permalink / raw) To: Pavel Begunkov Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev On Wed, Jul 22, 2026 at 3:59 AM Pavel Begunkov <asml.silence@gmail.com> wrote: > > We should either have net_iov or page backed frags in a single skb, > otherwise it blows up down the stack. Don't allow mixing in > zerocopy_fill_skb_from_devmem(). > > Fixes: bd61848900bff ("net: devmem: Implement TX path") > Cc: stable@vger.kernel.org > Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> It's true that we don't support mixing niov types and doing so would blow up, but this is an unnecessary defensive check imo. The calling code should not (and does not, I hope) have an edge case where it tries to mix and match niov types. Maybe a DEBUG_NET_WARN_ON check to help catch bugs in the calling code may be fine? Also we don't really support mixing different niov sub-types in an skb (like IO_URING + DMABUF) afaict, so might as well go the extra mile and check that it's all devmem niovs specifically. And might as well put the check in skb_add_rx_frag_netmem. It's the same situation on RX, we don't support mixing there (and I hope no code path leads to mixing today). -- Thanks, Mina ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-22 19:49 ` Mina Almasry @ 2026-07-22 20:20 ` Pavel Begunkov 2026-07-23 17:24 ` Bobby Eshleman 1 sibling, 0 replies; 7+ messages in thread From: Pavel Begunkov @ 2026-07-22 20:20 UTC (permalink / raw) To: Mina Almasry Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev On 7/22/26 20:49, Mina Almasry wrote: > On Wed, Jul 22, 2026 at 3:59 AM Pavel Begunkov <asml.silence@gmail.com> wrote: >> >> We should either have net_iov or page backed frags in a single skb, >> otherwise it blows up down the stack. Don't allow mixing in >> zerocopy_fill_skb_from_devmem(). >> >> Fixes: bd61848900bff ("net: devmem: Implement TX path") >> Cc: stable@vger.kernel.org >> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> > > It's true that we don't support mixing niov types and doing so would > blow up, but this is an unnecessary defensive check imo. The calling > code should not (and does not, I hope) have an edge case where it > tries to mix and match niov types. Nope, that can easily happen. > Maybe a DEBUG_NET_WARN_ON check to help catch bugs in the calling code > may be fine? > > Also we don't really support mixing different niov sub-types in an skb > (like IO_URING + DMABUF) afaict, so might as well go the extra mile > and check that it's all devmem niovs specifically. All those type intermixing rules might be flaky, maybe we should start with DEBUG_NET_WARN_ON, but at least for tx from a quick look it's handled by ubuf_info checks. > And might as well put the check in skb_add_rx_frag_netmem. It's the > same situation on RX, we don't support mixing there (and I hope no > code path leads to mixing today). A DEBUG_NET_WARN_ON there might be a very good idea, I agree. -- Pavel Begunkov ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-22 19:49 ` Mina Almasry 2026-07-22 20:20 ` Pavel Begunkov @ 2026-07-23 17:24 ` Bobby Eshleman 2026-07-23 18:35 ` Mina Almasry 1 sibling, 1 reply; 7+ messages in thread From: Bobby Eshleman @ 2026-07-23 17:24 UTC (permalink / raw) To: Mina Almasry Cc: Pavel Begunkov, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev On Wed, Jul 22, 2026 at 12:49:07PM -0700, Mina Almasry wrote: > On Wed, Jul 22, 2026 at 3:59 AM Pavel Begunkov <asml.silence@gmail.com> wrote: > > > > We should either have net_iov or page backed frags in a single skb, > > otherwise it blows up down the stack. Don't allow mixing in > > zerocopy_fill_skb_from_devmem(). > > > > Fixes: bd61848900bff ("net: devmem: Implement TX path") > > Cc: stable@vger.kernel.org > > Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> > > It's true that we don't support mixing niov types and doing so would > blow up, but this is an unnecessary defensive check imo. The calling > code should not (and does not, I hope) have an edge case where it > tries to mix and match niov types. > > Maybe a DEBUG_NET_WARN_ON check to help catch bugs in the calling code > may be fine? > > Also we don't really support mixing different niov sub-types in an skb > (like IO_URING + DMABUF) afaict, so might as well go the extra mile > and check that it's all devmem niovs specifically. > > And might as well put the check in skb_add_rx_frag_netmem. It's the > same situation on RX, we don't support mixing there (and I hope no > code path leads to mixing today). Hey Mina and Pavel, I was able to confirm this mixing case does exist. It looks like in tcp_sendmsg_locked() when new message is non-devmem (zc == 0) and tcp_write_queue_tail is devmem, the skb collapsing is allowed (though same-frag merge is disallowed). Adding a mode to ncdevmem that sends mixed devmem and non-devmem messages, it can be caught hacking this in: /* DEBUG (DROP ME): detect a TX skb that mixes devmem (net_iov, unreadable) * and non-devmem (page, readable) fragments. Such an skb must never exist. */ static bool tcp_dbg_skb_frags_mixed(const struct sk_buff *skb) { bool readable = false, unreadable = false; int i; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { if (skb_frag_is_net_iov(&skb_shinfo(skb)->frags[i])) unreadable = true; else readable = true; } return readable && unreadable; } static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, ...) { ... BUG_ON(!skb || !tcp_skb_pcount(skb)); WARN_ONCE(tcp_dbg_skb_frags_mixed(skb), "DEBUG: TX skb mixes devmem+non-devmem frags (nr_frags=%u len=%u)\n", skb_shinfo(skb)->nr_frags, skb->len); ... } Resulting in: [ 85.908005] DEBUG: TX skb mixes devmem+non-devmem frags (nr_frags=2 len=24) [ 85.908342] WARNING: net/ipv4/tcp_output.c:1570 at __tcp_transmit_skb+0x9bb/0x1030, CPU#2: ncdevmem/278 [ 85.910646] RIP: 0010:__tcp_transmit_skb+0x9c2/0x1030 ... [ 85.915617] tcp_write_xmit+0x47b/0x17d0 [ 85.915802] __tcp_push_pending_frames+0x38/0x100 [ 85.916025] tcp_sendmsg_locked+0xe51/0x1280 [ 85.916244] tcp_sendmsg+0x2c/0x50 [ 85.916903] do_syscall_64+0x11c/0x610 My feeling is that we should guard against this when tcp_sendmsg_locked() is doing its "new segment or not" calculus. In the zc == 0 case, I think we need to check if the queue tail is unreadable and 'goto new_segment' if it is? This is a different case than Pavel's patch addresses though, where the new sendmsg is devmem and write queue tail is readable. Best, Bobby ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/1] net: devmem: prevent net-iov / page mixing 2026-07-23 17:24 ` Bobby Eshleman @ 2026-07-23 18:35 ` Mina Almasry 0 siblings, 0 replies; 7+ messages in thread From: Mina Almasry @ 2026-07-23 18:35 UTC (permalink / raw) To: Bobby Eshleman Cc: Pavel Begunkov, David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev On Thu, Jul 23, 2026 at 10:24 AM Bobby Eshleman <bobbyeshleman@gmail.com> wrote: > > On Wed, Jul 22, 2026 at 12:49:07PM -0700, Mina Almasry wrote: > > On Wed, Jul 22, 2026 at 3:59 AM Pavel Begunkov <asml.silence@gmail.com> wrote: > > > > > > We should either have net_iov or page backed frags in a single skb, > > > otherwise it blows up down the stack. Don't allow mixing in > > > zerocopy_fill_skb_from_devmem(). > > > > > > Fixes: bd61848900bff ("net: devmem: Implement TX path") > > > Cc: stable@vger.kernel.org > > > Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> > > > > It's true that we don't support mixing niov types and doing so would > > blow up, but this is an unnecessary defensive check imo. The calling > > code should not (and does not, I hope) have an edge case where it > > tries to mix and match niov types. > > > > Maybe a DEBUG_NET_WARN_ON check to help catch bugs in the calling code > > may be fine? > > > > Also we don't really support mixing different niov sub-types in an skb > > (like IO_URING + DMABUF) afaict, so might as well go the extra mile > > and check that it's all devmem niovs specifically. > > > > And might as well put the check in skb_add_rx_frag_netmem. It's the > > same situation on RX, we don't support mixing there (and I hope no > > code path leads to mixing today). > > Hey Mina and Pavel, > > I was able to confirm this mixing case does exist. > > It looks like in tcp_sendmsg_locked() when new message is non-devmem (zc > == 0) and tcp_write_queue_tail is devmem, the skb collapsing is allowed > (though same-frag merge is disallowed). > > Adding a mode to ncdevmem that sends mixed devmem and non-devmem > messages, it can be caught hacking this in: > > /* DEBUG (DROP ME): detect a TX skb that mixes devmem (net_iov, unreadable) > * and non-devmem (page, readable) fragments. Such an skb must never exist. > */ > static bool tcp_dbg_skb_frags_mixed(const struct sk_buff *skb) > { > bool readable = false, unreadable = false; > int i; > > for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { > if (skb_frag_is_net_iov(&skb_shinfo(skb)->frags[i])) > unreadable = true; > else > readable = true; > } > return readable && unreadable; > } > > static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, ...) > { > ... > BUG_ON(!skb || !tcp_skb_pcount(skb)); > > WARN_ONCE(tcp_dbg_skb_frags_mixed(skb), > "DEBUG: TX skb mixes devmem+non-devmem frags (nr_frags=%u len=%u)\n", > skb_shinfo(skb)->nr_frags, skb->len); > ... > } > > > Resulting in: > > [ 85.908005] DEBUG: TX skb mixes devmem+non-devmem frags (nr_frags=2 len=24) > [ 85.908342] WARNING: net/ipv4/tcp_output.c:1570 at __tcp_transmit_skb+0x9bb/0x1030, CPU#2: ncdevmem/278 > [ 85.910646] RIP: 0010:__tcp_transmit_skb+0x9c2/0x1030 > ... > [ 85.915617] tcp_write_xmit+0x47b/0x17d0 > [ 85.915802] __tcp_push_pending_frames+0x38/0x100 > [ 85.916025] tcp_sendmsg_locked+0xe51/0x1280 > [ 85.916244] tcp_sendmsg+0x2c/0x50 > [ 85.916903] do_syscall_64+0x11c/0x610 > > > My feeling is that we should guard against this when > tcp_sendmsg_locked() is doing its "new segment or not" calculus. In the > zc == 0 case, I think we need to check if the queue tail is unreadable > and 'goto new_segment' if it is? > > This is a different case than Pavel's patch addresses though, where the > new sendmsg is devmem and write queue tail is readable. > :( Yep looks like we have a couple of bugs in the TX mixing. Sorry about that. We do indeed need to fix this ASAP. I don't think it's enough to check readable vs unreadable, no? Because I think appending io_uring niovs to a devmem skb will still blow up and vise versa, even though both are unreadable, right? Or is io_uring saved from this somehow in both cases? If io_uring is vulnerable to this as well, then fixing this becomes a bit more hairy because this is a TCP fast path. We don't have bits in the skb header telling us exactly what the skb memtype is (only readable vs not), so we'll have to check skb_frag_is_net_iov(frags[0]) and netmem_to_net_iov(frags[0]->netmem)->niov_type to check the exact type of the skb memtype, and that may be a lot of cachelines to fetch in the fast path. :( -- Thanks, Mina ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-23 18:35 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-22 10:58 [PATCH net 1/1] net: devmem: prevent net-iov / page mixing Pavel Begunkov 2026-07-22 17:59 ` Bobby Eshleman 2026-07-22 18:58 ` Pavel Begunkov 2026-07-22 19:49 ` Mina Almasry 2026-07-22 20:20 ` Pavel Begunkov 2026-07-23 17:24 ` Bobby Eshleman 2026-07-23 18:35 ` Mina Almasry
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox