summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiayuan Chen <jiayuan.chen@linux.dev>2025-04-25 13:59:57 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-06-19 15:31:48 +0200
commitc13e3174991cb1aa9d48dfd4f28591e0254b9fe1 (patch)
treedcd4fca06899f2e9d4741d669602857ab4032996
parent64f8f2a93358145d8dde73d67d8144ab1d4c95eb (diff)
ktls, sockmap: Fix missing uncharge operation
[ Upstream commit 79f0c39ae7d3dc628c01b02f23ca5d01f9875040 ] When we specify apply_bytes, we divide the msg into multiple segments, each with a length of 'send', and every time we send this part of the data using tcp_bpf_sendmsg_redir(), we use sk_msg_return_zero() to uncharge the memory of the specified 'send' size. However, if the first segment of data fails to send, for example, the peer's buffer is full, we need to release all of the msg. When releasing the msg, we haven't uncharged the memory of the subsequent segments. This modification does not make significant logical changes, but only fills in the missing uncharge places. This issue has existed all along, until it was exposed after we added the apply test in test_sockmap: commit 3448ad23b34e ("selftests/bpf: Add apply_bytes test to test_txmsg_redir_wait_sndmem in test_sockmap") Fixes: d3b18ad31f93 ("tls: add bpf support to sk_msg handling") Reported-by: Cong Wang <xiyou.wangcong@gmail.com> Closes: https://lore.kernel.org/bpf/aAmIi0vlycHtbXeb@pop-os.localdomain/T/#t Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Acked-by: John Fastabend <john.fastabend@gmail.com> Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com> Link: https://lore.kernel.org/r/20250425060015.6968-2-jiayuan.chen@linux.dev Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--net/tls/tls_sw.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index b3cae4dd4f49..8fb5925f2389 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -908,6 +908,13 @@ more_data:
&msg_redir, send, flags);
lock_sock(sk);
if (err < 0) {
+ /* Regardless of whether the data represented by
+ * msg_redir is sent successfully, we have already
+ * uncharged it via sk_msg_return_zero(). The
+ * msg->sg.size represents the remaining unprocessed
+ * data, which needs to be uncharged here.
+ */
+ sk_mem_uncharge(sk, msg->sg.size);
*copied -= sk_msg_free_nocharge(sk, &msg_redir);
msg->sg.size = 0;
}