Skip to contentSkip to conversation

Netfilter: Fix overlapping expectations in existing expectation code

PATCH In review Rusty Russell 1 participant 1 message Jan 11, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/8 Netfilter: Fix overlapping expectations in existing expectation code

Name: Fix overlapping expectations in existing expectation code
Status: Tested under nfsim

Change kmem_cache_free() calls in ip_conntrack_expect_related() to ip_conntrack_expect_put(): they should be equivalent but allows a hack in next patch (caller can keep expect).

More importantly, a previous expectation should only be refreshed and return EEXIST if it's owned by the same connection (nfsim found this bug).

net/ipv4/netfilter/ip_conntrack_core.c +4 -5
Index: linux-2.6.10-bk7-Netfilter/net/ipv4/netfilter/ip_conntrack_core.c
===================================================================
@@ -912,7 +902,7 @@
 	old = LIST_FIND(&ip_conntrack_expect_list, resent_expect,
 		        struct ip_conntrack_expect *, &expect->tuple, 
 			&expect->mask);
-	if (old) {
+	if (old && old->expectant == related_to) {
 		/* Helper private data may contain offsets but no pointers
 		   pointing into the payload - otherwise we should have to copy 
 		   the data filled out by the helper over the old one */
@@ -929,8 +919,7 @@
 		}
 
 		WRITE_UNLOCK(&ip_conntrack_lock);
-		/* This expectation is not inserted so no need to lock */
-		kmem_cache_free(ip_conntrack_expect_cachep, expect);
+		ip_conntrack_expect_put(expect);
 		return -EEXIST;
 
 	} else if (related_to->helper->max_expected && 
@@ -948,7 +937,7 @@
 				       related_to->helper->name,
  		    	       	       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
  		    	       	       NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
-			kmem_cache_free(ip_conntrack_expect_cachep, expect);
+			ip_conntrack_expect_put(expect);	
 			return -EPERM;
 		}
 		DEBUGP("ip_conntrack: max number of expected "
@@ -982,7 +971,7 @@
 		WRITE_UNLOCK(&ip_conntrack_lock);
 		DEBUGP("expect_related: busy!\n");
 
-		kmem_cache_free(ip_conntrack_expect_cachep, expect);
+		ip_conntrack_expect_put(expect);	
 		return -EBUSY;
 	}