Linux s390 Architecture development
 help / color / mirror / Atom feed
* [PATCH net] net/smc: queue the copied chunk when smc_tx_sendmsg() faults
@ 2026-10-13 20:45 Bryam Vargas via B4 Relay
  2026-10-13 20:49 ` netdev-bot+sinfo
  2026-10-13 20:52 ` sashiko-bot
  0 siblings, 2 replies; 3+ messages in thread
From: Bryam Vargas via B4 Relay @ 2026-10-13 20:45 UTC (permalink / raw)
  To: Jakub Kicinski, Dust Li, Paolo Abeni, Eric Dumazet,
	Mahanta Jambigi, David S. Miller, Sidraya Jayagond, D. Wythe
  Cc: netdev, Ursula Braun, linux-s390, Wen Gu, Simon Horman,
	linux-rdma, Hidayath Khan, Tony Lu, linux-kernel, Wenjia Zhang

From: Bryam Vargas <hexlabsecurity@proton.me>

When a send wraps the end of the send buffer, smc_tx_sendmsg() copies
the data in two chunks. If memcpy_from_msg() faults on the second one,
smc_tx_sendmsg() returns send_done, which already counts the first
chunk, but leaves tx_curs_prep and sndbuf_space as they were. send()
reports bytes the peer never receives, and the next send() overwrites
them. Any caller can hit this on its own stream with a buffer whose
tail is unreadable.

On a fault in the second chunk, queue the first one. The next pass
retries the rest and returns send_done if it faults again, so send()
reports only what it queued, as TCP does.

Fixes: e6727f39004b ("smc: send data (through RDMA)")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
---
Repro on v7.3-rc6 with KASAN (its smc_tx.c is the same as net's),
SMC-D loopback: send 33000 bytes, wait until the peer has read them
and SIOCOUTQ is 0, then send(S, MSG_DONTWAIT) from a buffer whose
first S - 500 bytes are readable and whose next page is PROT_NONE.
The 65504-byte sndbuf wraps after 32504 bytes, so at S = 65504 and
65536 the fault hits the second chunk:

  unpatched: send() returns 32504, SIOCOUTQ stays 0, and the peer
             gets only the 100-byte marker sent next.
  patched:   send() returns 32504 and the peer gets those bytes,
             intact, then the marker.

The 12 other sizes (16352 to 1048576) fault in the first chunk or not
at all, and give the same result on both kernels: -EFAULT, or 65504
sent and delivered. With the whole buffer readable, both deliver what
send() reports at every size. TCP at S = 65504 on the faulting buffer
returns 47616 and delivers exactly that. No KASAN splat. Logs on
request.

The rx side has the same shape: smc_rx_recvmsg() returns the first
chunk without moving the cursor when memcpy_to_msg() faults on the
second. Hidayath said in [1] that his v2 will fix it along with the
splice path, so this only touches smc_tx.c. It applies to net as is
and on top of [2], whose 3/4 also changes smc_tx_sendmsg(); the repro
gives the same results there.

[1] https://lore.kernel.org/all/7a174d1f-80d8-4294-ae66-829c9dacd662@linux.ibm.com/
[2] https://lore.kernel.org/all/20261013-b4-disp-f345196c-v7-0-ef3dddfbfa68@proton.me/
---
 net/smc/smc_tx.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/smc/smc_tx.c b/net/smc/smc_tx.c
index 3144b4b1fe29..495fb1354728 100644
--- a/net/smc/smc_tx.c
+++ b/net/smc/smc_tx.c
@@ -249,6 +249,13 @@ int smc_tx_sendmsg(struct smc_sock *smc, struct msghdr *msg, size_t len)
 			rc = memcpy_from_msg(sndbuf_base + chunk_off,
 					     msg, chunk_len);
 			if (rc) {
+				if (chunk) {
+					/* send_done counts the first chunk:
+					 * queue it and retry the rest
+					 */
+					copylen -= chunk_len;
+					break;
+				}
 				smc_sndbuf_sync_sg_for_device(conn);
 				if (send_done)
 					return send_done;

---
base-commit: 513444cc62e231a11c9b15ea88de0890da9b2b4f
change-id: 20261013-b4-disp-872a3689-f4666b3d8b6b

Best regards,
--  
Bryam Vargas <hexlabsecurity@proton.me>



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-13 20:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 20:45 [PATCH net] net/smc: queue the copied chunk when smc_tx_sendmsg() faults Bryam Vargas via B4 Relay
2026-10-13 20:49 ` netdev-bot+sinfo
2026-10-13 20:52 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox