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

netfilter: nf_tables: do not update stateful expressions if lookup is inverted

Initialize set lookup matching element to NULL. Otherwise, the
NFT_LOOKUP_F_INV flag reverses the matching logic and it leads to
deference an uninitialized pointer to the matching element. Make sure
element data area and stateful expression are accessed if there is a
matching set element.

This patch undoes 24791b9aa1ab ("netfilter: nft_set_bitmap: initialize set
element extension in lookups") which is not required anymore.

Fixes: 339706bc21c1 ("netfilter: nft_lookup: update element stateful expression")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+8 -7
+1 -1
include/net/netfilter/nf_tables.h
··· 901 901 { 902 902 struct nft_expr *expr; 903 903 904 - if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) { 904 + if (__nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) { 905 905 expr = nft_set_ext_expr(ext); 906 906 expr->ops->eval(expr, regs, pkt); 907 907 }
+7 -5
net/netfilter/nft_lookup.c
··· 29 29 { 30 30 const struct nft_lookup *priv = nft_expr_priv(expr); 31 31 const struct nft_set *set = priv->set; 32 - const struct nft_set_ext *ext; 32 + const struct nft_set_ext *ext = NULL; 33 33 bool found; 34 34 35 35 found = set->ops->lookup(nft_net(pkt), set, &regs->data[priv->sreg], ··· 39 39 return; 40 40 } 41 41 42 - if (set->flags & NFT_SET_MAP) 43 - nft_data_copy(&regs->data[priv->dreg], 44 - nft_set_ext_data(ext), set->dlen); 42 + if (ext) { 43 + if (set->flags & NFT_SET_MAP) 44 + nft_data_copy(&regs->data[priv->dreg], 45 + nft_set_ext_data(ext), set->dlen); 45 46 46 - nft_set_elem_update_expr(ext, regs, pkt); 47 + nft_set_elem_update_expr(ext, regs, pkt); 48 + } 47 49 } 48 50 49 51 static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
-1
net/netfilter/nft_set_bitmap.c
··· 81 81 u32 idx, off; 82 82 83 83 nft_bitmap_location(set, key, &idx, &off); 84 - *ext = NULL; 85 84 86 85 return nft_bitmap_active(priv->bitmap, idx, off, genmask); 87 86 }