Re: [PATCH net v2] esp: downgrade zerocopy managed frags before mutating skb frags

From: Steffen Klassert

Date: Tue Sep 01 2026 - 04:47:10 EST


On Mon, Aug 17, 2026 at 02:37:52PM +0100, Maher Azzouzi wrote:
> On the out-of-place output path (esp->inplace == false) ESP rewrites the
> skb frag array: esp_output_head() appends a trailer frag and
> esp_output_tail() replaces the frags with a destination page, both
> referenced with get_page().
>
> When the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the
> payload frags are owned by the ubuf and must not be referenced or
> unreferenced individually, but ESP mutates the frag array without ever
> downgrading the skb. This breaks the managed-frag invariant two ways:
>
> - esp_ssg_unref() walks the source scatterlist and drops a page
> reference for every frag, including the ubuf-owned payload frags,
> pushing their refcount below the GUP pin bias while the pages are
> still pinned, i.e. a use-after-free of the zerocopy pages;
>
> - esp_output_tail() installs its destination page as frag 0 with
> get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so
> skb_release_data() takes the skip_unref branch and never drops that
> reference, leaking the x->xfrag page at packet rate.
>
> Fix this the way every other frag-mutating site does (__ip_append_data(),
> __ip6_append_data(), tcp_sendmsg_locked()) and call
> skb_zcopy_downgrade_managed() before ESP touches the frag array: it takes
> a real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS,
> so the per-frag unref in esp_ssg_unref() and the frag release in
> skb_release_data() are both balanced and no mixed-ownership frag array is
> left behind.
>
> Fixes: 753f1ca4e1e5 ("net: introduce managed frags infrastructure")
> Signed-off-by: Maher Azzouzi <maherazz04@xxxxxxxxx>

Now applied to the ipsec tree, thanks a lot!