Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_set_rbtree: skip sync GC for new elements in this transaction

New elements in this transaction might expired before such transaction
ends. Skip sync GC for such elements otherwise commit path might walk
over an already released object. Once transaction is finished, async GC
will collect such expired element.

Fixes: f6c383b8c31a ("netfilter: nf_tables: adapt set backend to use GC transaction API")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>

authored by

Pablo Neira Ayuso and committed by
Florian Westphal
2ee52ae9 fdc04cc2

+6 -2
+6 -2
net/netfilter/nft_set_rbtree.c
··· 312 312 struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL; 313 313 struct rb_node *node, *next, *parent, **p, *first = NULL; 314 314 struct nft_rbtree *priv = nft_set_priv(set); 315 + u8 cur_genmask = nft_genmask_cur(net); 315 316 u8 genmask = nft_genmask_next(net); 316 317 int d, err; 317 318 ··· 358 357 if (!nft_set_elem_active(&rbe->ext, genmask)) 359 358 continue; 360 359 361 - /* perform garbage collection to avoid bogus overlap reports. */ 362 - if (nft_set_elem_expired(&rbe->ext)) { 360 + /* perform garbage collection to avoid bogus overlap reports 361 + * but skip new elements in this transaction. 362 + */ 363 + if (nft_set_elem_expired(&rbe->ext) && 364 + nft_set_elem_active(&rbe->ext, cur_genmask)) { 363 365 err = nft_rbtree_gc_elem(set, priv, rbe, genmask); 364 366 if (err < 0) 365 367 return err;