From: Antony Antony A concurrent delete can free the migrated state before xfrm_do_migrate_state() finishes using it. Fixes: a9d155ea9b44 ("xfrm: add XFRM_MSG_MIGRATE_STATE for single SA migration") Reported-by: Sashiko Signed-off-by: Antony Antony Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5a9f729b4fcb..8640838dcda0 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -3509,6 +3509,7 @@ static int xfrm_do_migrate_state(struct sk_buff *skb, struct nlmsghdr *nlh, __xfrm_state_delete(x); spin_unlock_bh(&x->lock); + xfrm_state_hold(xc); err = xfrm_state_migrate_install(x, xc, &m, extack); if (err < 0) { /* @@ -3516,6 +3517,7 @@ static int xfrm_do_migrate_state(struct sk_buff *skb, struct nlmsghdr *nlh, * free under xfrm_cfg_mutex. Both SAs are gone if it does; * restoring x would risk SN/IV reuse. */ + xfrm_state_put(xc); goto out; } @@ -3534,6 +3536,7 @@ static int xfrm_do_migrate_state(struct sk_buff *skb, struct nlmsghdr *nlh, err = 0; } + xfrm_state_put(xc); out: xfrm_state_put(x); return err; -- 2.53.0