CVE-2026-46102
Description
In the Linux kernel, the following vulnerability has been resolved:
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.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In the Linux kernel's stream parser (net/strparser), strp_abort_strp() leaks a partially assembled message (skb_head), allowing repeated memory exhaustion.
Vulnerability
In the Linux kernel's stream parser (net/strparser), the function strp_abort_strp() is called when stream parsing is aborted, e.g., after a message assembly timeout. A partial message may be held in strp->skb_head, but the function does not release this socket buffer, causing a memory leak [1]. The vulnerability affects all kernel versions containing this code path; the fix was backported to stable trees [2], [3], [4].
Exploitation
An attacker with the ability to trigger stream parser aborts (for example, by sending partial or malformed data to a socket that uses the stream parser, causing timeouts) can repeatedly cause strp_abort_strp() to execute while a partially assembled message is outstanding. No authentication or special privileges are required beyond network access to the affected socket endpoint.
Impact
Each such abort leaks a socket buffer (skb_head) that was still in use. Repeated triggers can exhaust system memory, leading to denial of service (kernel memory exhaustion). The leak does not enable arbitrary code execution or privilege escalation, but can make the system unresponsive or crash it due to out-of-memory conditions.
Mitigation
The fix must be applied by updating the Linux kernel to a version containing the corresponding stable commit [1]. The patch releases strp->skb_head and resets the parser state in strp_abort_strp(), while leaving strp_stop() unchanged for final cleanup in strp_done(). Affected users should upgrade to corrected kernels from their distribution vendor. No workaround beyond a kernel update is currently available.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
10fe72340daaf1net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index fe0e76fdd1f1cd..a23f4b4dfc6733 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; -- cgit 1.3-korg
e9ae00490d47net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index b61384b08e7c3a..2a805c964210c3 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; -- cgit 1.3-korg
5327dad2ffe9net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index b61384b08e7c3a..2a805c964210c3 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; -- cgit 1.3-korg
56082f442023net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index fe0e76fdd1f1cd..a23f4b4dfc6733 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; -- cgit 1.3-korg
19ca9475f18fnet: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index e659fea2da70f8..e3c6abe58f4442 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; -- cgit 1.3-korg
56082f442023net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index fe0e76fdd1f1cd..a23f4b4dfc6733 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; -- cgit 1.3-korg
fe72340daaf1net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index fe0e76fdd1f1cd..a23f4b4dfc6733 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; -- cgit 1.3-korg
19ca9475f18fnet: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index e659fea2da70f8..e3c6abe58f4442 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; -- cgit 1.3-korg
5327dad2ffe9net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index b61384b08e7c3a..2a805c964210c3 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; -- cgit 1.3-korg
e9ae00490d47net: strparser: fix skb_head leak in strp_abort_strp()
1 file changed · +8 −1
net/strparser/strparser.c+8 −1 modifieddiff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index b61384b08e7c3a..2a805c964210c3 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; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing skb free in strp_abort_strp() leaks a reference to a partially assembled message."
Attack vector
An attacker can trigger the stream parser to abort, for example by causing a message assembly timeout, while a partially assembled message is held in `strp->skb_head`. Because `strp_abort_strp()` does not free that skb, each abort leaks one skb. By repeatedly triggering aborts, the attacker can exhaust kernel memory, leading to a denial-of-service condition. No special privileges are required beyond the ability to send data to a socket using the stream parser.
Affected code
The vulnerability is in the `strp_abort_strp()` function in `net/strparser/strparser.c` [patch_id=2659693]. The function sets `strp->stopped = 1` but does not release the partially assembled socket buffer referenced by `strp->skb_head`.
What the fix does
The patch adds a check for `strp->skb_head` in `strp_abort_strp()` and, if non-NULL, calls `kfree_skb()` to free it and sets the pointer to NULL [patch_id=2659693]. It also resets `strp->skb_nextp` to NULL and `strp->need_bytes` to 0, fully cleaning up the parser state. This ensures that no skb reference is leaked when the parser is aborted, preventing the memory exhaustion attack.
Preconditions
- networkThe attacker must be able to send data to a socket that uses the kernel's stream parser (strparser).
- inputThe attacker must be able to trigger an abort condition (e.g., message assembly timeout) while a partially assembled message exists.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/19ca9475f18f991735f98a22e735c43e95e6298dnvd
- git.kernel.org/stable/c/5327dad2ffe9c1b49881dd6d51ff3c6893847568nvd
- git.kernel.org/stable/c/56082f442023db9be1a5a29d4ee361de4017c0b7nvd
- git.kernel.org/stable/c/e9ae00490d474757c0f9c65073de83e6bb1e5a00nvd
- git.kernel.org/stable/c/fe72340daaf1af588be88056faf98965f39e6032nvd
News mentions
0No linked articles in our index yet.