From: netdev-bot+sashiko@kernel.org
To: juny24602@gmail.com
Cc: steffen.klassert@secunet.com, herbert@gondor.apana.org.au,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org,
shinta.sugimoto@ericsson.com, yoshfuji@linux-ipv6.org,
nakam@linux-ipv6.org, netdev@vger.kernel.org,
junvyyang@tencent.com, stable@kernel.org, corvus@tencent.com
Subject: Re: [PATCH net] xfrm: delete migrated old states before dropping their references
Date: Tue, 10 Nov 2026 09:19:20 +0000 [thread overview]
Message-ID: <179430236030.994134.16814357178144716775@kernel.org> (raw)
In-Reply-To: <20261106090300.29203-1-juny24602@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 1 · Medium: 0 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [High] This patch fixes the Stage 4 x_cur[] path but leaves a matching
use-after-free on the restore_state error path in xfrm_migrate()…
--
xfrm: delete migrated old states before dropping their references
This patch reorders Stage 4 of xfrm_migrate() so the old states in x_cur[]
are deleted before their lookup references are dropped. The states then
stay alive during xfrm_states_delete(), even if an expiry timer or a
concurrent deletion has already removed them from the state tables.
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index cea6842e6454d..39ca04432220b 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -4726,8 +4726,8 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
>
> /* Stage 4 - delete old state(s) */
> if (nx_cur) {
> - xfrm_states_put(x_cur, nx_cur);
> xfrm_states_delete(x_cur, nx_cur);
> + xfrm_states_put(x_cur, nx_cur);
> }
[Severity: High]
This fixes the x_cur[] path. Does the restore_state error path in
xfrm_migrate() still have the same use-after-free for the x_new[] states?
net/xfrm/xfrm_policy.c:xfrm_migrate() {
...
restore_state:
if (pol)
xfrm_pol_put(pol);
if (nx_cur)
xfrm_states_put(x_cur, nx_cur);
if (nx_new)
xfrm_states_delete(x_new, nx_new);
...
}
In Stage 2 the new state is stored without taking a reference:
xc = xfrm_state_migrate(x, mp, net, extack);
if (xc) {
x_new[nx_new] = xc;
nx_new++;
By this point xfrm_state_migrate()->xfrm_state_migrate_install() has
already published xc with xfrm_state_insert() or xfrm_state_add(). The
state tables now own its only reference, and __xfrm_state_insert() has
armed mtimer.
Once published, xc can be found by SPI lookup on the data path. Its curlft
was copied from the old SA by xfrm_migrate_sync(). That means it can be
deleted without xfrm_cfg_mutex, for example:
xfrm_state_check_expire() /* hard byte/packet limit reached */
hrtimer_start(&x->mtimer, 0, HRTIMER_MODE_REL_SOFT);
xfrm_timer_handler()
__xfrm_state_delete()
xfrm_state_put() /* drops the only reference */
The 1s mtimer reaching hard_add_expires with the copied add_time has the
same effect.
Userspace can still reach restore_state after xc has been published. One
way is xfrm_policy_migrate() returning -ENODATA (no template matches) or
-ENOENT (dead policy). Another is a later entry's xfrm_state_migrate()
returning NULL, for example -EEXIST from xfrm_state_add(). That later
entry's xfrm_state_migrate_create() allocates with GFP_KERNEL and can
sleep, which makes the window wider.
If xc has already been freed by then, xfrm_state_delete(xc) would take
xc->lock and read xc->km.state on freed memory. If the slab has been
reused, this could also lead to list corruption and another put.
Reordering cannot fix this one, because xfrm_migrate() never holds its own
reference on the x_new[] entries. Could a reference be taken on xc before
it is installed? The parallel path xfrm_do_migrate_state() in xfrm_user.c
already does this:
xfrm_state_hold(xc);
err = xfrm_state_migrate_install(x, xc, &m, extack);
That reference would then be dropped after xfrm_states_delete() in
restore_state, or on the success path.
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261106090300.29203-1-juny24602%40gmail.com
prev parent reply other threads:[~2026-11-10 9:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 9:02 [PATCH net] xfrm: delete migrated old states before dropping their references Jun Yang
2026-11-10 9:19 ` netdev-bot+sashiko [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=179430236030.994134.16814357178144716775@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=corvus@tencent.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=horms@kernel.org \
--cc=junvyyang@tencent.com \
--cc=juny24602@gmail.com \
--cc=kuba@kernel.org \
--cc=nakam@linux-ipv6.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shinta.sugimoto@ericsson.com \
--cc=stable@kernel.org \
--cc=steffen.klassert@secunet.com \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox