diff options
-rw-r--r-- | net/xfrm/xfrm_policy.c | 31 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 6 |
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 | ||
298 | static void xfrm_policy_kill(struct xfrm_policy *policy) | 298 | static 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 | |||
776 | int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | 766 | int 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; |