summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLuxiao Xu <rakukuip@gmail.com>2026-04-11 23:10:10 +0800
committerPaolo Abeni <pabeni@redhat.com>2026-04-14 12:37:00 +0200
commitfe72340daaf1af588be88056faf98965f39e6032 (patch)
tree8ee13a6c8e65e32f4a6bcf6009d81cfd35067cb1
parent600dc40554dc5ad1e6f3af51f700228033f43ea7 (diff)
downloadwireguard-linux-fe72340daaf1af588be88056faf98965f39e6032.tar.xz
wireguard-linux-fe72340daaf1af588be88056faf98965f39e6032.zip
net: strparser: fix skb_head leak in strp_abort_strp()
When the stream parser is aborted, for example after a message assembly timeout, it can still hold a reference to a partially assembled message in strp->skb_head. That skb is not released in strp_abort_strp(), which leaks the partially assembled message and can be triggered repeatedly to exhaust memory. Fix this by freeing strp->skb_head and resetting the parser state in the abort path. Leave strp_stop() unchanged so final cleanup still happens in strp_done() after the work and timer have been synchronized. Fixes: 43a0c6751a32 ("strparser: Stream parser for messages") Cc: stable@kernel.org Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Co-developed-by: Yuan Tan <yuantan098@gmail.com> Signed-off-by: Yuan Tan <yuantan098@gmail.com> Suggested-by: Xin Liu <bird@lzu.edu.cn> Tested-by: Yuan Tan <yuantan098@gmail.com> Signed-off-by: Luxiao Xu <rakukuip@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Link: https://patch.msgid.link/ade3857a9404999ce9a1c27ec523efc896072678.1775482694.git.rakukuip@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--net/strparser/strparser.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c
index fe0e76fdd1f1..a23f4b4dfc67 100644
--- a/net/strparser/strparser.c
+++ b/net/strparser/strparser.c
@@ -45,6 +45,14 @@ static void strp_abort_strp(struct strparser *strp, int err)
strp->stopped = 1;
+ if (strp->skb_head) {
+ kfree_skb(strp->skb_head);
+ strp->skb_head = NULL;
+ }
+
+ strp->skb_nextp = NULL;
+ strp->need_bytes = 0;
+
if (strp->sk) {
struct sock *sk = strp->sk;