Re: [PATCH net-next v8] l2tp: fix double dst_release() on sk_dst_cache race

From: Mikhail Lobanov

Date: Mon Jun 01 2026 - 17:27:34 EST


On Tue, 16 Dec 2025 08:35:41 -0800 Jakub Kicinski wrote:
> This seems to be causing a leak:
>
> unreferenced object 0xffff888017774e40 (size 64):
> comm "ip", pid 3486, jiffies 4298584595
> [...]
> crypto_rfc4106_init_tfm+0x41/0x190
> [...]
> esp_init_aead.constprop.0+0xe4/0x340
> esp_init_state+0x83/0x4c0
> __xfrm_init_state+0x6f2/0x13d0
> xfrm_state_construct+0x1455/0x2480 [xfrm_user]
> xfrm_add_sa+0x137/0x3c0 [xfrm_user]
> xfrm_user_rcv_msg+0x502/0x920 [xfrm_user]

Thanks for running this. I don't believe this patch is the source of
the leak.

The leaked object is the AEAD transform of an IPsec ESP SA. It is
allocated by the XFRM control plane when userspace adds an SA
("ip xfrm state add", comm "ip"): xfrm_add_sa() -> __xfrm_init_state()
-> esp_init_state() -> esp_init_aead() -> crypto_alloc_aead(). Its
lifetime is bound to the xfrm_state: esp_init_state() stores the aead in
x->data, and it is released by the state destructor esp_destroy() ->
crypto_free_aead() (.destructor = esp_destroy in net/ipv{4,6}/esp{4,6}.c).

This patch only rewrites the L2TP data-plane transmit path
(l2tp_xmit_queue() and the new l2tp_xmit_ipv4()/l2tp_xmit_ipv6()
helpers). That path never calls xfrm_add_sa() / esp_init_state() /
esp_init_aead() (so it does not allocate this tfm), never calls
esp_destroy() / crypto_free_aead() (so it does not free it), and does
not touch xfrm_state lifetime, so it cannot change the refcounting of
the reported object. The leaking call chain executes no L2TP code.

I could not reproduce the leak under kmemleak, with or without this
patch. Li Xiasong reported the same in this thread: the patch fixes the
race, and the leak does not reproduce for him either.

Could you share the exact test/steps that produced the report? It looks
like one of the IPsec/xfrm selftests rather than anything L2TP, and I'm
happy to chase that pre-existing path down separately.

I'll send v9 (rebased on net-next, fix unchanged) shortly.

Thanks,
Mikhail