From e0e8f1c8220c43bdf25cfb5622f6ab6947027fb1 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 10 Jan 2007 22:06:32 -0800
Subject: [PATCH] [IPSEC] flow: Fix potential memory leak

When old flow cache entries that are not at the head of their chain
trigger a transient security error they get unlinked along with all
the entries preceding them in the chain.  The preceding entries are
not freed correctly.

This patch fixes this by simply leaving the entry around.  It's based
on a suggestion by Venkat Yekkirala.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/core/flow.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/net/core/flow.c b/net/core/flow.c
index d137f971f97d..5d25697920b1 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -231,22 +231,16 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
 
 		err = resolver(key, family, dir, &obj, &obj_ref);
 
-		if (fle) {
-			if (err) {
-				/* Force security policy check on next lookup */
-				*head = fle->next;
-				flow_entry_kill(cpu, fle);
-			} else {
-				fle->genid = atomic_read(&flow_cache_genid);
-
-				if (fle->object)
-					atomic_dec(fle->object_ref);
-
-				fle->object = obj;
-				fle->object_ref = obj_ref;
-				if (obj)
-					atomic_inc(fle->object_ref);
-			}
+		if (fle && !err) {
+			fle->genid = atomic_read(&flow_cache_genid);
+
+			if (fle->object)
+				atomic_dec(fle->object_ref);
+
+			fle->object = obj;
+			fle->object_ref = obj_ref;
+			if (obj)
+				atomic_inc(fle->object_ref);
 		}
 		local_bh_enable();
 
-- 
2.30.9