All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kaifeng Wang <kaifengw@google.com>
To: netdev@vger.kernel.org
Cc: edumazet@google.com, ncardwell@google.com, kuniyu@google.com,
	 davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
	horms@kernel.org,  asml.silence@gmail.com,
	almasrymina@google.com, willemb@google.com,  kaiyuanz@google.com,
	sdf@fomichev.me, linux-kernel@vger.kernel.org,
	 Kaifeng Wang <kaifengw@google.com>
Subject: [PATCH net v2] tcp: reject devmem tx with fastopen and repair
Date: Mon, 19 Oct 2026 17:45:22 +0000	[thread overview]
Message-ID: <20261019174522.55644-1-kaifengw@google.com> (raw)

tcp_sendmsg_locked() enforces that devmem TX can only proceed if the
zero-copy path is active and a valid dmabuf binding exists. However,
subsequent branches in tcp_sendmsg_locked() can still intercept the
message before it reaches the devmem zero-copy loop:

1. TCP Fast Open (MSG_FASTOPEN or DEFER_CONNECT):
   If TCP_FASTOPEN_CONNECT is set, the socket may have a valid dst with
   NETIF_F_SG (so zc == MSG_ZEROCOPY and binding is present), but
   tcp_sendmsg_fastopen() -> tcp_send_syn_data() will use
   copy_page_from_iter() to byte-copy from the iterator. Since iov_base
   represents dma-buf offsets rather than user virtual addresses, this
   misinterprets offsets as user pointers and copies the caller's memory
   at those addresses into the SYN packet.

2. TCP repair mode:
   If tp->repair is enabled with TCP_RECV_QUEUE, tcp_send_rcvq() similarly
   calls skb_copy_datagram_from_iter(), byte-copying from the iterator.

Neither path supports or makes sense for devmem transmission. Reject
devmem sends inside the Fast Open and TCP repair branches when a devmem
binding is present. Checking inside the tp->repair branch also covers
the case where repair mode is enabled while sk_stream_wait_connect()
drops the socket lock.

Additionally, drop the !sockc_err gate from the devmem validation check
and return sockc_err if set. Otherwise, if a valid SCM_DEVMEM_DMABUF is
followed by a failing cmsg, sockc.dmabuf_id remains set while binding is
not acquired, allowing the Fast Open and TCP_RECV_QUEUE repair paths to
proceed and return before sockc_err is checked.

This pre-existing issue was identified by Sashiko AI review on commit
125755776bc6 ("tcp: reject non zerocopy devmem tx") and has not been
hit in production.

Fixes: 125755776bc6 ("tcp: reject non zerocopy devmem tx")
Fixes: bd61848900bf ("net: devmem: Implement TX path")
Reviewed-by: Mina Almasry <almasrymina@google.com>
Signed-off-by: Kaifeng Wang <kaifengw@google.com>
---
v1 -> v2:
- Move the devmem rejection checks into the Fast Open and TCP repair
  branches directly, also covering the case where tp->repair is enabled
  while sk_stream_wait_connect() drops the socket lock.
- Drop the !sockc_err gate from the devmem validation check and return
  sockc_err if set, preventing a valid SCM_DEVMEM_DMABUF followed by a
  failing cmsg from bypassing the check.

 net/ipv4/tcp.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 87ef6d5cbfeb..2792923f0748 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1169,14 +1169,18 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
 			zc = MSG_SPLICE_PAGES;
 	}
 
-	if (!sockc_err && sockc.dmabuf_id && (zc != MSG_ZEROCOPY || !binding)) {
-		err = -EINVAL;
+	if (sockc.dmabuf_id && (zc != MSG_ZEROCOPY || !binding)) {
+		err = sockc_err ?: -EINVAL;
 		goto out_err;
 	}
 
 	if (unlikely(flags & MSG_FASTOPEN ||
 		     inet_test_bit(DEFER_CONNECT, sk)) &&
 	    !tp->repair) {
+		if (binding) {
+			err = -EINVAL;
+			goto out_err;
+		}
 		err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size, uarg);
 		if (err == -EINPROGRESS && copied_syn > 0)
 			goto out;
@@ -1200,6 +1204,10 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
 	}
 
 	if (unlikely(tp->repair)) {
+		if (binding) {
+			err = -EINVAL;
+			goto out_err;
+		}
 		if (tp->repair_queue == TCP_RECV_QUEUE) {
 			copied = tcp_send_rcvq(sk, msg, size);
 			goto out_nopush;
-- 
2.56.0.385.gd3acb90ef8-goog

             reply	other threads:[~2026-10-19 17:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 17:45 Kaifeng Wang [this message]
2026-10-20 16:54 ` [PATCH net v2] tcp: reject devmem tx with fastopen and repair Stanislav Fomichev

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=20261019174522.55644-1-kaifengw@google.com \
    --to=kaifengw@google.com \
    --cc=almasrymina@google.com \
    --cc=asml.silence@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kaiyuanz@google.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ncardwell@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    --cc=willemb@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.