mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net/smc: queue the copied chunk when smc_tx_sendmsg() faults
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: e6727f3900 ("smc: send data (through RDMA)")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20261013-b4-disp-872a3689-v1-1-2a4c63b04761@proton.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
9043be310c
commit
c0703534b2
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user