aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/xfrm/xfrm_policy.c31
-rw-r--r--net/xfrm/xfrm_user.c6
2 files changed, 10 insertions, 27 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 843e066649cb..82789cf1c632 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -156,7 +156,7 @@ static void xfrm_policy_timer(unsigned long data)
156 156
157 read_lock(&xp->lock); 157 read_lock(&xp->lock);
158 158
159 if (xp->walk.dead) 159 if (unlikely(xp->walk.dead))
160 goto out; 160 goto out;
161 161
162 dir = xfrm_policy_id2dir(xp->index); 162 dir = xfrm_policy_id2dir(xp->index);
@@ -297,17 +297,7 @@ static DECLARE_WORK(xfrm_policy_gc_work, xfrm_policy_gc_task);
297 297
298static void xfrm_policy_kill(struct xfrm_policy *policy) 298static void xfrm_policy_kill(struct xfrm_policy *policy)
299{ 299{
300 int dead;
301
302 write_lock_bh(&policy->lock);
303 dead = policy->walk.dead;
304 policy->walk.dead = 1; 300 policy->walk.dead = 1;
305 write_unlock_bh(&policy->lock);
306
307 if (unlikely(dead)) {
308 WARN_ON(1);
309 return;
310 }
311 301
312 spin_lock_bh(&xfrm_policy_gc_lock); 302 spin_lock_bh(&xfrm_policy_gc_lock);
313 hlist_add_head(&policy->bydst, &xfrm_policy_gc_list); 303 hlist_add_head(&policy->bydst, &xfrm_policy_gc_list);
@@ -776,7 +766,6 @@ xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audi
776int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) 766int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
777{ 767{
778 int dir, err = 0, cnt = 0; 768 int dir, err = 0, cnt = 0;
779 struct xfrm_policy *dp;
780 769
781 write_lock_bh(&xfrm_policy_lock); 770 write_lock_bh(&xfrm_policy_lock);
782 771
@@ -794,10 +783,9 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
794 &net->xfrm.policy_inexact[dir], bydst) { 783 &net->xfrm.policy_inexact[dir], bydst) {
795 if (pol->type != type) 784 if (pol->type != type)
796 continue; 785 continue;
797 dp = __xfrm_policy_unlink(pol, dir); 786 __xfrm_policy_unlink(pol, dir);
798 write_unlock_bh(&xfrm_policy_lock); 787 write_unlock_bh(&xfrm_policy_lock);
799 if (dp) 788 cnt++;
800 cnt++;
801 789
802 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid, 790 xfrm_audit_policy_delete(pol, 1, audit_info->loginuid,
803 audit_info->sessionid, 791 audit_info->sessionid,
@@ -816,10 +804,9 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info)
816 bydst) { 804 bydst) {
817 if (pol->type != type) 805 if (pol->type != type)
818 continue; 806 continue;
819 dp = __xfrm_policy_unlink(pol, dir); 807 __xfrm_policy_unlink(pol, dir);
820 write_unlock_bh(&xfrm_policy_lock); 808 write_unlock_bh(&xfrm_policy_lock);
821 if (dp) 809 cnt++;
822 cnt++;
823 810
824 xfrm_audit_policy_delete(pol, 1, 811 xfrm_audit_policy_delete(pol, 1,
825 audit_info->loginuid, 812 audit_info->loginuid,
@@ -1132,6 +1119,9 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
1132 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); 1119 __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
1133 } 1120 }
1134 if (old_pol) 1121 if (old_pol)
1122 /* Unlinking succeeds always. This is the only function
1123 * allowed to delete or replace socket policy.
1124 */
1135 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir); 1125 __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
1136 write_unlock_bh(&xfrm_policy_lock); 1126 write_unlock_bh(&xfrm_policy_lock);
1137 1127
@@ -1737,11 +1727,8 @@ restart:
1737 goto error; 1727 goto error;
1738 } 1728 }
1739 1729
1740 for (pi = 0; pi < npols; pi++) { 1730 for (pi = 0; pi < npols; pi++)
1741 read_lock_bh(&pols[pi]->lock);
1742 pol_dead |= pols[pi]->walk.dead; 1731 pol_dead |= pols[pi]->walk.dead;
1743 read_unlock_bh(&pols[pi]->lock);
1744 }
1745 1732
1746 write_lock_bh(&policy->lock); 1733 write_lock_bh(&policy->lock);
1747 if (unlikely(pol_dead || stale_bundle(dst))) { 1734 if (unlikely(pol_dead || stale_bundle(dst))) {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index da5ba86181de..a267fbdda525 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1770,13 +1770,9 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1770 if (xp == NULL) 1770 if (xp == NULL)
1771 return -ENOENT; 1771 return -ENOENT;
1772 1772
1773 read_lock(&xp->lock); 1773 if (unlikely(xp->walk.dead))
1774 if (xp->walk.dead) {
1775 read_unlock(&xp->lock);
1776 goto out; 1774 goto out;
1777 }
1778 1775
1779 read_unlock(&xp->lock);
1780 err = 0; 1776 err = 0;
1781 if (up->hard) { 1777 if (up->hard) {
1782 uid_t loginuid = NETLINK_CB(skb).loginuid; 1778 uid_t loginuid = NETLINK_CB(skb).loginuid;