diff options
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.patch | 105 |
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 - |