Netdev List
 help / color / mirror / Atom feed
* [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