Commit 2e2a7207 authored by Fernando Fernandez Mancera's avatar Fernando Fernandez Mancera Committed by Florian Westphal
Browse files

netfilter: nf_conncount: fix leaked ct in error paths



There are some situations where ct might be leaked as error paths are
skipping the refcounted check and return immediately. In order to solve
it make sure that the check is always called.

Fixes: be102eb6 ("netfilter: nf_conncount: rework API to use sk_buff directly")
Signed-off-by: default avatarFernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent 6bcb7727
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
	struct nf_conn *found_ct;
	unsigned int collect = 0;
	bool refcounted = false;
	int err = 0;

	if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted))
		return -ENOENT;

	if (ct && nf_ct_is_confirmed(ct)) {
		if (refcounted)
			nf_ct_put(ct);
		return -EEXIST;
		err = -EEXIST;
		goto out_put;
	}

	if ((u32)jiffies == list->last_gc)
@@ -231,12 +231,16 @@ static int __nf_conncount_add(struct net *net,
	}

add_new_node:
	if (WARN_ON_ONCE(list->count > INT_MAX))
		return -EOVERFLOW;
	if (WARN_ON_ONCE(list->count > INT_MAX)) {
		err = -EOVERFLOW;
		goto out_put;
	}

	conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
	if (conn == NULL)
		return -ENOMEM;
	if (conn == NULL) {
		err = -ENOMEM;
		goto out_put;
	}

	conn->tuple = tuple;
	conn->zone = *zone;
@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
out_put:
	if (refcounted)
		nf_ct_put(ct);
	return 0;
	return err;
}

int nf_conncount_add_skb(struct net *net,
@@ -456,11 +460,10 @@ insert_tree(struct net *net,

		rb_link_node_rcu(&rbconn->node, parent, rbnode);
		rb_insert_color(&rbconn->node, root);

		if (refcounted)
			nf_ct_put(ct);
	}
out_unlock:
	if (refcounted)
		nf_ct_put(ct);
	spin_unlock_bh(&nf_conncount_locks[hash]);
	return count;
}