mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-16 22:51:32 +00:00
netfilter: nf_tables: fix race when create new element in dynset
Packets may race when create the new element in nft_hash_update: CPU0 CPU1 lookup_fast - fail lookup_fast - fail new - ok new - ok insert - ok insert - fail(EEXIST) So when race happened, we reuse the existing element. Otherwise, these *racing* packets will not be handled properly. Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates") Signed-off-by: Liping Zhang <zlpnobody@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
61f9e2924f
commit
dab45060a5
@ -98,7 +98,7 @@ static bool nft_hash_update(struct nft_set *set, const u32 *key,
|
||||
const struct nft_set_ext **ext)
|
||||
{
|
||||
struct nft_hash *priv = nft_set_priv(set);
|
||||
struct nft_hash_elem *he;
|
||||
struct nft_hash_elem *he, *prev;
|
||||
struct nft_hash_cmp_arg arg = {
|
||||
.genmask = NFT_GENMASK_ANY,
|
||||
.set = set,
|
||||
@ -112,9 +112,18 @@ static bool nft_hash_update(struct nft_set *set, const u32 *key,
|
||||
he = new(set, expr, regs);
|
||||
if (he == NULL)
|
||||
goto err1;
|
||||
if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
|
||||
nft_hash_params))
|
||||
|
||||
prev = rhashtable_lookup_get_insert_key(&priv->ht, &arg, &he->node,
|
||||
nft_hash_params);
|
||||
if (IS_ERR(prev))
|
||||
goto err2;
|
||||
|
||||
/* Another cpu may race to insert the element with the same key */
|
||||
if (prev) {
|
||||
nft_set_elem_destroy(set, he, true);
|
||||
he = prev;
|
||||
}
|
||||
|
||||
out:
|
||||
*ext = &he->ext;
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user