nft_connlimit_eval() reads priv->list->count to check if the connection limit has been exceeded. This value can be cached by the CPU while it can be decremented by a different CPU when a connection is closed. This causes a data race as the value cached might be outdated. When a new connection is established and evaluated by the connlimit expression, priv->list->count is incremented by nf_conncount_add(), triggering the CPU's cache coherency protocol and therefore refreshing the cached value before updating it. Solve this situation by reading the value using READ_ONCE(). Fixes: df4a90250976 ("netfilter: nf_conncount: merge lookup and add functions") Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ Signed-off-by: Fernando Fernandez Mancera --- net/netfilter/nft_connlimit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c index 92b984fa8175..fc35a11cdca2 100644 --- a/net/netfilter/nft_connlimit.c +++ b/net/netfilter/nft_connlimit.c @@ -48,7 +48,7 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, return; } - count = priv->list->count; + count = READ_ONCE(priv->list->count); if ((count > priv->limit) ^ priv->invert) { regs->verdict.code = NFT_BREAK; -- 2.51.0