]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfrm: call xfrm_dev_policy_delete when kill policy
authorJianbo Liu <jianbol@nvidia.com>
Mon, 8 Jul 2024 06:58:12 +0000 (09:58 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 3 Aug 2024 06:59:44 +0000 (08:59 +0200)
[ Upstream commit 89a2aefe4b084686c2ffc1ee939585111ea4fc0f ]

xfrm_policy_kill() is called at different places to delete xfrm
policy. It will call xfrm_pol_put(). But xfrm_dev_policy_delete() is
not called to free the policy offloaded to hardware.

The three commits cited here are to handle this issue by calling
xfrm_dev_policy_delete() outside xfrm_get_policy(). But they didn't
cover all the cases. An example, which is not handled for now, is
xfrm_policy_insert(). It is called when XFRM_MSG_UPDPOLICY request is
received. Old policy is replaced by new one, but the offloaded policy
is not deleted, so driver doesn't have the chance to release hardware
resources.

To resolve this issue for all cases, move xfrm_dev_policy_delete()
into xfrm_policy_kill(), so the offloaded policy can be deleted from
hardware when it is called, which avoids hardware resources leakage.

Fixes: 919e43fad516 ("xfrm: add an interface to offload policy")
Fixes: bf06fcf4be0f ("xfrm: add missed call to delete offloaded policies")
Fixes: 982c3aca8bac ("xfrm: delete offloaded policy")
Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c

index 66e07de2de35cd1b5d3b4b5771e152dde6660b0d..56b88ad88db6f97712819cb62c8651deda8b0139 100644 (file)
@@ -452,6 +452,8 @@ EXPORT_SYMBOL(xfrm_policy_destroy);
 
 static void xfrm_policy_kill(struct xfrm_policy *policy)
 {
+       xfrm_dev_policy_delete(policy);
+
        write_lock_bh(&policy->lock);
        policy->walk.dead = 1;
        write_unlock_bh(&policy->lock);
@@ -1850,7 +1852,6 @@ again:
 
                __xfrm_policy_unlink(pol, dir);
                spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
-               xfrm_dev_policy_delete(pol);
                cnt++;
                xfrm_audit_policy_delete(pol, 1, task_valid);
                xfrm_policy_kill(pol);
@@ -1891,7 +1892,6 @@ again:
 
                __xfrm_policy_unlink(pol, dir);
                spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
-               xfrm_dev_policy_delete(pol);
                cnt++;
                xfrm_audit_policy_delete(pol, 1, task_valid);
                xfrm_policy_kill(pol);
@@ -2342,7 +2342,6 @@ int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
        pol = __xfrm_policy_unlink(pol, dir);
        spin_unlock_bh(&net->xfrm.xfrm_policy_lock);
        if (pol) {
-               xfrm_dev_policy_delete(pol);
                xfrm_policy_kill(pol);
                return 0;
        }
index e83c687bd64ee9c80de7c9cbfc91d5b6dcbff3fb..77355422ce82a2df96c1afe1ad364669855be42a 100644 (file)
@@ -2455,7 +2455,6 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
                                            NETLINK_CB(skb).portid);
                }
        } else {
-               xfrm_dev_policy_delete(xp);
                xfrm_audit_policy_delete(xp, err ? 0 : 1, true);
 
                if (err != 0)