summaryrefslogtreecommitdiff
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorLeon Romanovsky <leonro@nvidia.com>2023-04-19 15:19:07 +0300
committerSteffen Klassert <steffen.klassert@secunet.com>2023-04-21 08:51:48 +0200
commit94b95dfaa814f565d92f5a65f0ff12a483095522 (patch)
tree4d9cbd03534a1e68a295a04e017d8af67279b8b6 /net/xfrm/xfrm_user.c
parent430cac487400494c19a8b85299e979bb07b4671f (diff)
xfrm: release all offloaded policy memory
Failure to add offloaded policy will cause to the following error once user will try to reload driver. Unregister_netdevice: waiting for eth3 to become free. Usage count = 2 This was caused by xfrm_dev_policy_add() which increments reference to net_device. That reference was supposed to be decremented in xfrm_dev_policy_free(). However the latter wasn't called. unregister_netdevice: waiting for eth3 to become free. Usage count = 2 leaked reference. xfrm_dev_policy_add+0xff/0x3d0 xfrm_policy_construct+0x352/0x420 xfrm_add_policy+0x179/0x320 xfrm_user_rcv_msg+0x1d2/0x3d0 netlink_rcv_skb+0xe0/0x210 xfrm_netlink_rcv+0x45/0x50 netlink_unicast+0x346/0x490 netlink_sendmsg+0x3b0/0x6c0 sock_sendmsg+0x73/0xc0 sock_write_iter+0x13b/0x1f0 vfs_write+0x528/0x5d0 ksys_write+0x120/0x150 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Fixes: 919e43fad516 ("xfrm: add an interface to offload policy") Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 103af2b3e986..af8fbcbfbe69 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1978,6 +1978,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err) {
xfrm_dev_policy_delete(xp);
+ xfrm_dev_policy_free(xp);
security_xfrm_policy_free(xp->security);
kfree(xp);
return err;