summaryrefslogtreecommitdiffstats
path: root/main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch')
-rw-r--r--main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch105
1 files changed, 0 insertions, 105 deletions
diff --git a/main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch b/main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch
deleted file mode 100644
index 222caaddf..000000000
--- a/main/linux-grsec/0012-xfrm-remove-policy-lock-when-accessing-policy-walk.d.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 7a400eb025dd53883c3560d0fdb069542f7ad3db Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
-Date: Wed, 31 Mar 2010 00:17:05 +0000
-Subject: [PATCH 12/18] xfrm: remove policy lock when accessing policy->walk.dead
-
-All of the code considers ->dead as a hint that the cached policy
-needs to get refreshed. The read side can just drop the read lock
-without any side effects.
-
-The write side needs to make sure that it's written only exactly
-once. Only possible race is at xfrm_policy_kill(). This is fixed
-by checking result of __xfrm_policy_unlink() when needed. It will
-always succeed if the policy object is looked up from the hash
-list (so some checks are removed), but it needs to be checked if
-we are trying to unlink policy via a reference (appropriate
-checks added).
-
-Since policy->walk.dead is written exactly once, it no longer
-needs to be protected with a write lock.
-
-Signed-off-by: Timo Teras <timo.teras@iki.fi>
-Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-(backported from commit ea2dea9dacc256fe927857feb423872051642ae7)
----
- net/xfrm/xfrm_policy.c | 20 +++++---------------
- net/xfrm/xfrm_user.c | 6 +-----
- 2 files changed, 6 insertions(+), 20 deletions(-)
-
-diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
-index d75047c..110184f 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)
-
- read_lock(&xp->lock);
-
-- if (xp->walk.dead)
-+ if (unlikely(xp->walk.dead))
- goto out;
-
- dir = xfrm_policy_id2dir(xp->index);
-@@ -297,17 +297,7 @@ static DECLARE_WORK(xfrm_policy_gc_work, xfrm_policy_gc_task);
-
- static void xfrm_policy_kill(struct xfrm_policy *policy)
- {
-- int dead;
--
-- write_lock_bh(&policy->lock);
-- dead = policy->walk.dead;
- policy->walk.dead = 1;
-- write_unlock_bh(&policy->lock);
--
-- if (unlikely(dead)) {
-- WARN_ON(1);
-- return;
-- }
-
- spin_lock_bh(&xfrm_policy_gc_lock);
- hlist_add_head(&policy->bydst, &xfrm_policy_gc_list);
-@@ -1115,6 +1105,9 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
- __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
- }
- if (old_pol)
-+ /* Unlinking succeeds always. This is the only function
-+ * allowed to delete or replace socket policy.
-+ */
- __xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
- write_unlock_bh(&xfrm_policy_lock);
-
-@@ -1705,11 +1698,8 @@ restart:
- goto error;
- }
-
-- for (pi = 0; pi < npols; pi++) {
-- read_lock_bh(&pols[pi]->lock);
-+ for (pi = 0; pi < npols; pi++)
- pol_dead |= pols[pi]->walk.dead;
-- read_unlock_bh(&pols[pi]->lock);
-- }
-
- write_lock_bh(&policy->lock);
- if (unlikely(pol_dead || stale_bundle(dst))) {
-diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
-index d1e9ee3..f9c56e9 100644
---- a/net/xfrm/xfrm_user.c
-+++ b/net/xfrm/xfrm_user.c
-@@ -1617,13 +1617,9 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
- if (xp == NULL)
- return -ENOENT;
-
-- read_lock(&xp->lock);
-- if (xp->walk.dead) {
-- read_unlock(&xp->lock);
-+ if (unlikely(xp->walk.dead))
- goto out;
-- }
-
-- read_unlock(&xp->lock);
- err = 0;
- if (up->hard) {
- uid_t loginuid = NETLINK_CB(skb).loginuid;
---
-1.7.0.2
-