Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1565

kernel-2.6.18-128.1.10.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Subject: [RHEL 5.1 PATCH] stop leak in flow cache code
Date: Wed, 04 Apr 2007 17:56:26 -0400
Bugzilla: 229528
Message-Id: <1175723786.20396.171.camel@localhost.localdomain>
Changelog: [net] stop leak in flow cache code


In the middle of a discussion about another issue upstream noticed a bug
in which if the resolver returned an err and the fle was not at the head
of the list all previous entries were simply leaked since we move the
head past the fle in question.  The upstream solution was to simply
leave everything alone if the resolver returned an error and so do a
full lookup again the next time.

This patch has been in the LSPP kernel for quite some time with no
negative effects.  Although admittedly no method was determined to
reasonably get into the situation in question at will for explicit
testing purposes.

see:
http://marc.info/?l=linux-netdev&m=116845095029169&w=2
with patch from:
http://marc.info/?l=linux-netdev&m=116847167008802&w=2

-Eric

--- linux-2.6.18.i386/net/core/flow.c.pre.229528	2007-02-22 10:43:18.000000000 -0500
+++ linux-2.6.18.i386/net/core/flow.c	2007-02-22 10:46:16.000000000 -0500
@@ -231,22 +231,16 @@ nocache:
 
 		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();