netfilter: nft_range: validate operation netlink attribute
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 13 Oct 2016 06:42:17 +0000 (08:42 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 17 Oct 2016 16:57:02 +0000 (18:57 +0200)
Use nft_parse_u32_check() to make sure we don't get a value over the
unsigned 8-bit integer. Moreover, make sure this value doesn't go over
the two supported range comparison modes.

Fixes: 9286c2eb1fda ("netfilter: nft_range: validate operation netlink attribute")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nft_range.c

index c6d5358482d12ce81b8f4782e72ba2dcdbfb1caa..9bc4586c3006cb60d308cd02a78453b124c146a9 100644 (file)
@@ -59,6 +59,7 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
        struct nft_range_expr *priv = nft_expr_priv(expr);
        struct nft_data_desc desc_from, desc_to;
        int err;
+       u32 op;
 
        err = nft_data_init(NULL, &priv->data_from, sizeof(priv->data_from),
                            &desc_from, tb[NFTA_RANGE_FROM_DATA]);
@@ -80,7 +81,20 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
        if (err < 0)
                goto err2;
 
-       priv->op  = ntohl(nla_get_be32(tb[NFTA_RANGE_OP]));
+       err = nft_parse_u32_check(tb[NFTA_RANGE_OP], U8_MAX, &op);
+       if (err < 0)
+               goto err2;
+
+       switch (op) {
+       case NFT_RANGE_EQ:
+       case NFT_RANGE_NEQ:
+               break;
+       default:
+               err = -EINVAL;
+               goto err2;
+       }
+
+       priv->op  = op;
        priv->len = desc_from.len;
        return 0;
 err2: