aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-05-29 03:36:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-31 20:30:07 -0400
commite4c1721642bbd42d8142f4811cde0588c28db51d (patch)
tree8f7750f6065dcb5d2bd727174fb9f4e3cd8fccf3
parent1e2bd517c108816220f262d7954b697af03b5f9c (diff)
xfrm: force a garbage collection after deleting a policy
In some cases after deleting a policy from the SPD the policy would remain in the dst/flow/route cache for an extended period of time which caused problems for SELinux as its dynamic network access controls key off of the number of XFRM policy and state entries. This patch corrects this problem by forcing a XFRM garbage collection whenever a policy is sucessfully removed. Reported-by: Ondrej Moris <omoris@redhat.com> Signed-off-by: Paul Moore <pmoore@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/xfrm.h5
-rw-r--r--net/key/af_key.c4
-rw-r--r--net/xfrm/xfrm_policy.c3
-rw-r--r--net/xfrm/xfrm_user.c2
4 files changed, 13 insertions, 1 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ae16531d0d35..94ce082b29dc 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1160,6 +1160,8 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
1160 } 1160 }
1161} 1161}
1162 1162
1163extern void xfrm_garbage_collect(struct net *net);
1164
1163#else 1165#else
1164 1166
1165static inline void xfrm_sk_free_policy(struct sock *sk) {} 1167static inline void xfrm_sk_free_policy(struct sock *sk) {}
@@ -1194,6 +1196,9 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
1194{ 1196{
1195 return 1; 1197 return 1;
1196} 1198}
1199static inline void xfrm_garbage_collect(struct net *net)
1200{
1201}
1197#endif 1202#endif
1198 1203
1199static __inline__ 1204static __inline__
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 5b1e5af25713..c5fbd7589681 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2366,6 +2366,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
2366 2366
2367out: 2367out:
2368 xfrm_pol_put(xp); 2368 xfrm_pol_put(xp);
2369 if (err == 0)
2370 xfrm_garbage_collect(net);
2369 return err; 2371 return err;
2370} 2372}
2371 2373
@@ -2615,6 +2617,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_
2615 2617
2616out: 2618out:
2617 xfrm_pol_put(xp); 2619 xfrm_pol_put(xp);
2620 if (delete && err == 0)
2621 xfrm_garbage_collect(net);
2618 return err; 2622 return err;
2619} 2623}
2620 2624
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 23cea0f74336..ea970b8002a2 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2557,11 +2557,12 @@ static void __xfrm_garbage_collect(struct net *net)
2557 } 2557 }
2558} 2558}
2559 2559
2560static void xfrm_garbage_collect(struct net *net) 2560void xfrm_garbage_collect(struct net *net)
2561{ 2561{
2562 flow_cache_flush(); 2562 flow_cache_flush();
2563 __xfrm_garbage_collect(net); 2563 __xfrm_garbage_collect(net);
2564} 2564}
2565EXPORT_SYMBOL(xfrm_garbage_collect);
2565 2566
2566static void xfrm_garbage_collect_deferred(struct net *net) 2567static void xfrm_garbage_collect_deferred(struct net *net)
2567{ 2568{
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index aa778748c565..3f565e495ac6 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1681,6 +1681,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1681 1681
1682out: 1682out:
1683 xfrm_pol_put(xp); 1683 xfrm_pol_put(xp);
1684 if (delete && err == 0)
1685 xfrm_garbage_collect(net);
1684 return err; 1686 return err;
1685} 1687}
1686 1688