Commit 13b9f4df authored by Rusty Russell's avatar Rusty Russell Committed by David S. Miller

[NETFILTER]: Fix overlapping expectations in existing expectation code

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).
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 85ef7720
...@@ -912,7 +912,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -912,7 +912,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
old = LIST_FIND(&ip_conntrack_expect_list, resent_expect, old = LIST_FIND(&ip_conntrack_expect_list, resent_expect,
struct ip_conntrack_expect *, &expect->tuple, struct ip_conntrack_expect *, &expect->tuple,
&expect->mask); &expect->mask);
if (old) { if (old && old->expectant == related_to) {
/* Helper private data may contain offsets but no pointers /* Helper private data may contain offsets but no pointers
pointing into the payload - otherwise we should have to copy pointing into the payload - otherwise we should have to copy
the data filled out by the helper over the old one */ the data filled out by the helper over the old one */
...@@ -929,8 +929,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -929,8 +929,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
} }
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
/* This expectation is not inserted so no need to lock */ ip_conntrack_expect_put(expect);
kmem_cache_free(ip_conntrack_expect_cachep, expect);
return -EEXIST; return -EEXIST;
} else if (related_to->helper->max_expected && } else if (related_to->helper->max_expected &&
...@@ -948,7 +947,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -948,7 +947,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
related_to->helper->name, related_to->helper->name,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.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; return -EPERM;
} }
DEBUGP("ip_conntrack: max number of expected " DEBUGP("ip_conntrack: max number of expected "
...@@ -982,7 +981,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, ...@@ -982,7 +981,7 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
WRITE_UNLOCK(&ip_conntrack_lock); WRITE_UNLOCK(&ip_conntrack_lock);
DEBUGP("expect_related: busy!\n"); DEBUGP("expect_related: busy!\n");
kmem_cache_free(ip_conntrack_expect_cachep, expect); ip_conntrack_expect_put(expect);
return -EBUSY; return -EBUSY;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment