netfilter: nft_limit: do not ignore unsupported flags
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 9 Jan 2024 23:42:37 +0000 (00:42 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 17 Jan 2024 11:02:47 +0000 (12:02 +0100)
Bail out if userspace provides unsupported flags, otherwise future
extensions to the limit expression will be silently ignored by the
kernel.

Fixes: c7862a5f0de5 ("netfilter: nft_limit: allow to invert matching criteria")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nft_limit.c

index 145dc62c62472605e9f99c6e69f240e4c66774e9..79039afde34ecb1ca9fe1494855676ab26e7c53b 100644 (file)
@@ -58,6 +58,7 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
 static int nft_limit_init(struct nft_limit_priv *priv,
                          const struct nlattr * const tb[], bool pkts)
 {
+       bool invert = false;
        u64 unit, tokens;
 
        if (tb[NFTA_LIMIT_RATE] == NULL ||
@@ -90,19 +91,23 @@ static int nft_limit_init(struct nft_limit_priv *priv,
                                 priv->rate);
        }
 
+       if (tb[NFTA_LIMIT_FLAGS]) {
+               u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
+
+               if (flags & ~NFT_LIMIT_F_INV)
+                       return -EOPNOTSUPP;
+
+               if (flags & NFT_LIMIT_F_INV)
+                       invert = true;
+       }
+
        priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT);
        if (!priv->limit)
                return -ENOMEM;
 
        priv->limit->tokens = tokens;
        priv->tokens_max = priv->limit->tokens;
-
-       if (tb[NFTA_LIMIT_FLAGS]) {
-               u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
-
-               if (flags & NFT_LIMIT_F_INV)
-                       priv->invert = true;
-       }
+       priv->invert = invert;
        priv->limit->last = ktime_get_ns();
        spin_lock_init(&priv->limit->lock);