Re: CVE-2026-43284: xfrm: esp: avoid in-place decrypt on shared skb frags

From: Massimiliano Pellizzer

Date: Fri May 08 2026 - 04:59:07 EST


On Fri, May 8, 2026 at 9:24 AM Greg Kroah-Hartman
<gregkh@xxxxxxxxxxxxxxxxxxx> wrote:
>
> From: Greg Kroah-Hartman <gregkh@xxxxxxxxxx>
>
> Description
> ===========
>
> In the Linux kernel, the following vulnerability has been resolved:
>
> xfrm: esp: avoid in-place decrypt on shared skb frags
>
> MSG_SPLICE_PAGES can attach pages from a pipe directly to an skb. TCP
> marks such skbs with SKBFL_SHARED_FRAG after skb_splice_from_iter(),
> so later paths that may modify packet data can first make a private
> copy. The IPv4/IPv6 datagram append paths did not set this flag when
> splicing pages into UDP skbs.
>
> That leaves an ESP-in-UDP packet made from shared pipe pages looking
> like an ordinary uncloned nonlinear skb. ESP input then takes the no-COW
> fast path for uncloned skbs without a frag_list and decrypts in place
> over data that is not owned privately by the skb.
>
> Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG, matching
> TCP. Also make ESP input fall back to skb_cow_data() when the flag is
> present, so ESP does not decrypt externally backed frags in place.
> Private nonlinear skb frags still use the existing fast path.
>
> This intentionally does not change ESP output. In esp_output_head(),
> the path that appends the ESP trailer to existing skb tailroom without
> calling skb_cow_data() is not reachable for nonlinear skbs:
> skb_tailroom() returns zero when skb->data_len is nonzero, while ESP
> tailen is positive. Thus ESP output will either use the separate
> destination-frag path or fall back to skb_cow_data().
>
> The Linux kernel CVE team has assigned CVE-2026-43284 to this issue.
>
>
> Affected and fixed versions
> ===========================
>
> Issue introduced in 6.5 with commit 7da0dde68486b2d5bd7c689a9b327b77efecdfd0 and fixed in 6.6.138 with commit 50ed1e7873100f77abad20fd31c51029bc49cd03
> Issue introduced in 6.5 with commit 7da0dde68486b2d5bd7c689a9b327b77efecdfd0 and fixed in 6.12.87 with commit b54edf1e9a3fd3491bdcb82a21f8d21315271e0d
> Issue introduced in 6.5 with commit 7da0dde68486b2d5bd7c689a9b327b77efecdfd0 and fixed in 6.18.28 with commit 71a1d9d985d26716f74d21f18ee8cac821b06e97
> Issue introduced in 6.5 with commit 7da0dde68486b2d5bd7c689a9b327b77efecdfd0 and fixed in 7.0.5 with commit 52646cbd00e765a6db9c3afe9535f26218276034
>
> Please see https://www.kernel.org for a full list of currently supported
> kernel versions by the kernel community.
>
> Unaffected versions might change over time as fixes are backported to
> older supported kernel versions. The official CVE entry at
> https://cve.org/CVERecord/?id=CVE-2026-43284
> will be updated if fixes are backported, please check that for the most
> up to date information about this issue.
>
>
> Affected files
> ==============
>
> The file(s) affected by this issue are:
> net/ipv4/esp4.c
> net/ipv4/ip_output.c
> net/ipv6/esp6.c
> net/ipv6/ip6_output.c
>
>
> Mitigation
> ==========
>
> The Linux kernel CVE team recommends that you update to the latest
> stable kernel version for this, and many other bugfixes. Individual
> changes are never tested alone, but rather are part of a larger kernel
> release. Cherry-picking individual commits is not recommended or
> supported by the Linux kernel community at all. If however, updating to
> the latest release is impossible, the individual changes to resolve this
> issue can be found at these commits:
> https://git.kernel.org/stable/c/50ed1e7873100f77abad20fd31c51029bc49cd03
> https://git.kernel.org/stable/c/b54edf1e9a3fd3491bdcb82a21f8d21315271e0d
> https://git.kernel.org/stable/c/71a1d9d985d26716f74d21f18ee8cac821b06e97
> https://git.kernel.org/stable/c/52646cbd00e765a6db9c3afe9535f26218276034
> https://git.kernel.org/stable/c/f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4
>

I tested the publicly available exploit against the stable kernel 5.15.204.
That stable branch is affected too.

```
$ ./run.sh
=== Stage 1 — overwrite 'systemd-timesync' line (89 bytes) with
'sick::0:0:<pad>:/:/bin/bash'
=== Stage 2 — verify
sick::0:0:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:/:/bin/bash
=== Stage 3 — su - sick (empty password via PAM nullok)
[i] state saved to /var/tmp/.cf2.state — run './run.sh --clean' to revert
# whoami
root
# uname -r
5.15.204
```