Commit 0d2c96af authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nf_tables: validate NFT_DATA_VALUE after nft_data_init()



Userspace might bogusly sent NFT_DATA_VERDICT in several netlink
attributes that assume NFT_DATA_VALUE. Moreover, make sure that error
path invokes nft_data_release() to decrement the reference count on the
chain object.

Fixes: 96518518 ("netfilter: add nftables")
Fixes: 0f3cd9b3 ("netfilter: nf_tables: add range expression")
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent bffc124b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -4519,8 +4519,10 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
		return err;

	err = -EINVAL;
	if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
	if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) {
		nft_data_release(&elem.key.val, desc.type);
		return err;
	}

	priv = set->ops->get(ctx->net, set, &elem, flags);
	if (IS_ERR(priv))
+2 −2
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
			    tb[NFTA_BITWISE_MASK]);
	if (err < 0)
		return err;
	if (d1.len != priv->len) {
	if (d1.type != NFT_DATA_VALUE || d1.len != priv->len) {
		err = -EINVAL;
		goto err1;
	}
@@ -89,7 +89,7 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
			    tb[NFTA_BITWISE_XOR]);
	if (err < 0)
		goto err1;
	if (d2.len != priv->len) {
	if (d2.type != NFT_DATA_VALUE || d2.len != priv->len) {
		err = -EINVAL;
		goto err2;
	}
+6 −0
Original line number Diff line number Diff line
@@ -81,6 +81,12 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
	if (err < 0)
		return err;

	if (desc.type != NFT_DATA_VALUE) {
		err = -EINVAL;
		nft_data_release(&priv->data, desc.type);
		return err;
	}

	priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
	err = nft_validate_register_load(priv->sreg, desc.len);
	if (err < 0)
+10 −0
Original line number Diff line number Diff line
@@ -66,11 +66,21 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
	if (err < 0)
		return err;

	if (desc_from.type != NFT_DATA_VALUE) {
		err = -EINVAL;
		goto err1;
	}

	err = nft_data_init(NULL, &priv->data_to, sizeof(priv->data_to),
			    &desc_to, tb[NFTA_RANGE_TO_DATA]);
	if (err < 0)
		goto err1;

	if (desc_to.type != NFT_DATA_VALUE) {
		err = -EINVAL;
		goto err2;
	}

	if (desc_from.len != desc_to.len) {
		err = -EINVAL;
		goto err2;