]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nft_dynset: annotate data-races around set timeout
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 2 Sep 2024 23:08:49 +0000 (01:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2024 14:37:24 +0000 (16:37 +0200)
[ Upstream commit c5ad8ed61fa8410b272c077ec167c593602b4542 ]

set timeout can be read locklessly while being updated from control
plane, add annotation.

Fixes: 123b99619cca ("netfilter: nf_tables: honor set timeout and garbage collection updates")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/netfilter/nft_dynset.c

index b4ada3ab21679bc4e69f5810cd5590b7a2bbac96..489a9b34f1ecc1851a6380a3719dc496fdd3a90e 100644 (file)
@@ -56,7 +56,7 @@ static struct nft_elem_priv *nft_dynset_new(struct nft_set *set,
        if (!atomic_add_unless(&set->nelems, 1, set->size))
                return NULL;
 
-       timeout = priv->timeout ? : set->timeout;
+       timeout = priv->timeout ? : READ_ONCE(set->timeout);
        elem_priv = nft_set_elem_init(set, &priv->tmpl,
                                      &regs->data[priv->sreg_key], NULL,
                                      &regs->data[priv->sreg_data],
@@ -95,7 +95,7 @@ void nft_dynset_eval(const struct nft_expr *expr,
                             expr, regs, &ext)) {
                if (priv->op == NFT_DYNSET_OP_UPDATE &&
                    nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
-                       timeout = priv->timeout ? : set->timeout;
+                       timeout = priv->timeout ? : READ_ONCE(set->timeout);
                        *nft_set_ext_expiration(ext) = get_jiffies_64() + timeout;
                }
 
@@ -313,7 +313,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                nft_dynset_ext_add_expr(priv);
 
        if (set->flags & NFT_SET_TIMEOUT) {
-               if (timeout || set->timeout) {
+               if (timeout || READ_ONCE(set->timeout)) {
                        nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_TIMEOUT);
                        nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
                }