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
next 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.