Skip to content

Commit 2e2a720

Browse files
Fernando Fernandez ManceraFlorian Westphal
authored andcommitted
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: be102eb ("netfilter: nf_conncount: rework API to use sk_buff directly") Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Florian Westphal <fw@strlen.de>
1 parent 6bcb772 commit 2e2a720

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

net/netfilter/nf_conncount.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ static int __nf_conncount_add(struct net *net,
172172
struct nf_conn *found_ct;
173173
unsigned int collect = 0;
174174
bool refcounted = false;
175+
int err = 0;
175176

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

179180
if (ct && nf_ct_is_confirmed(ct)) {
180-
if (refcounted)
181-
nf_ct_put(ct);
182-
return -EEXIST;
181+
err = -EEXIST;
182+
goto out_put;
183183
}
184184

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

233233
add_new_node:
234-
if (WARN_ON_ONCE(list->count > INT_MAX))
235-
return -EOVERFLOW;
234+
if (WARN_ON_ONCE(list->count > INT_MAX)) {
235+
err = -EOVERFLOW;
236+
goto out_put;
237+
}
236238

237239
conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC);
238-
if (conn == NULL)
239-
return -ENOMEM;
240+
if (conn == NULL) {
241+
err = -ENOMEM;
242+
goto out_put;
243+
}
240244

241245
conn->tuple = tuple;
242246
conn->zone = *zone;
@@ -249,7 +253,7 @@ static int __nf_conncount_add(struct net *net,
249253
out_put:
250254
if (refcounted)
251255
nf_ct_put(ct);
252-
return 0;
256+
return err;
253257
}
254258

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

457461
rb_link_node_rcu(&rbconn->node, parent, rbnode);
458462
rb_insert_color(&rbconn->node, root);
459-
460-
if (refcounted)
461-
nf_ct_put(ct);
462463
}
463464
out_unlock:
465+
if (refcounted)
466+
nf_ct_put(ct);
464467
spin_unlock_bh(&nf_conncount_locks[hash]);
465468
return count;
466469
}

0 commit comments

Comments
 (0)