From: Hui Peng <benquike@gmail.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com
Cc: horms@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] kcm: fix socket memory accounting leak on TX completion, error, and close
Date: Sat, 19 Sep 2026 21:28:53 +0000 [thread overview]
Message-ID: <20260919212853.3240951-1-benquike@gmail.com> (raw)
In `kcm_sendmsg()`, every TX fragment is charged to both
`sk->sk_wmem_queued` and `sk->sk_forward_alloc` (`sk_mem_charge()`) via
`skb_copy_to_page_nocache()` or `MSG_SPLICE_PAGES`. However, the
assembled `head` skb is queued onto `&sk->sk_write_queue` (or held in
`kcm->seq_skb`) without `head->sk` or a destructor set.
Consequently:
1. When `kcm_write_msgs()` finishes transmitting `head`, it subtracts
`txm->sent` from `sk->sk_wmem_queued` but never calls
`sk_mem_uncharge(sk, txm->sent)`.
2. When `kcm_sendmsg()` fails under `out_error`, or when `kcm_release()`
frees `kcm->seq_skb` and purges `&sk->sk_write_queue`, `kfree_skb()`
is called without decrementing `sk->sk_wmem_queued` or calling
`sk_mem_uncharge()`, triggering a `WARN_ON` in `inet_sock_destruct()`
and `__sk_destruct()` when the KCM socket is closed.
Use `sk_wmem_queued_add(sk, -...)` and `sk_mem_uncharge(sk, ...)`
whenever freeing TX skbs in `kcm_write_msgs()`, `kcm_sendmsg()`, and
`kcm_release()`.
Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
---
net/kcm/kcmsock.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index 71af69d442f2..accf0d427e11 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -693,7 +693,8 @@ static int kcm_write_msgs(struct kcm_sock *kcm)
}
/* Successfully sent the whole packet, account for it. */
- sk->sk_wmem_queued -= txm->sent;
+ sk_wmem_queued_add(sk, -txm->sent);
+ sk_mem_uncharge(sk, txm->sent);
total_sent += txm->sent;
skb_dequeue(&sk->sk_write_queue);
kfree_skb(head);
@@ -960,10 +961,17 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
*/
if (copied)
goto partial_message;
- if (head != kcm->seq_skb)
+ if (head && head != kcm->seq_skb) {
+ sk_wmem_queued_add(sk, -head->len);
+ sk_mem_uncharge(sk, head->len);
kfree_skb(head);
+ }
} else {
- kfree_skb(head);
+ if (head) {
+ sk_wmem_queued_add(sk, -head->len);
+ sk_mem_uncharge(sk, head->len);
+ kfree_skb(head);
+ }
kcm->seq_skb = NULL;
}
@@ -1686,6 +1694,7 @@ static int kcm_release(struct socket *sock)
struct kcm_sock *kcm;
struct kcm_mux *mux;
struct kcm_psock *psock;
+ struct sk_buff *skb;
if (!sk)
return 0;
@@ -1695,13 +1704,21 @@ static int kcm_release(struct socket *sock)
lock_sock(sk);
sock_orphan(sk);
- kfree_skb(kcm->seq_skb);
+ if (kcm->seq_skb) {
+ sk_wmem_queued_add(sk, -kcm->seq_skb->len);
+ sk_mem_uncharge(sk, kcm->seq_skb->len);
+ kfree_skb(kcm->seq_skb);
+ }
/* Purge queue under lock to avoid race condition with tx_work trying
* to act when queue is nonempty. If tx_work runs after this point
* it will just return.
*/
- __skb_queue_purge(&sk->sk_write_queue);
+ while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
+ sk_wmem_queued_add(sk, -skb->len);
+ sk_mem_uncharge(sk, skb->len);
+ kfree_skb(skb);
+ }
release_sock(sk);
--
2.55.0.1082.g2b9226bbc0-goog
reply other threads:[~2026-09-19 21:28 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260919212853.3240951-1-benquike@gmail.com \
--to=benquike@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®