Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d07db988 authored by Patrick McHardy's avatar Patrick McHardy Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: introduce nft_validate_register_load()



Change nft_validate_input_register() to not only validate the input
register number, but also the length of the load, and rename it to
nft_validate_register_load() to reflect that change.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 27e6d201
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -112,13 +112,12 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
	return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
}

int nft_validate_input_register(enum nft_registers reg);
int nft_validate_register_load(enum nft_registers reg, unsigned int len);
int nft_validate_register_store(const struct nft_ctx *ctx,
				enum nft_registers reg,
				const struct nft_data *data,
				enum nft_data_types type, unsigned int len);


/**
 *	struct nft_userdata - user defined data associated with an object
 *
+9 −4
Original line number Diff line number Diff line
@@ -4122,22 +4122,27 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
}

/**
 *	nft_validate_input_register - validate an expressions' input register
 *	nft_validate_register_load - validate a load from a register
 *
 *	@reg: the register number
 *	@len: the length of the data
 *
 * 	Validate that the input register is one of the general purpose
 * 	registers.
 * 	registers and that the length of the load is within the bounds.
 */
int nft_validate_input_register(enum nft_registers reg)
int nft_validate_register_load(enum nft_registers reg, unsigned int len)
{
	if (reg <= NFT_REG_VERDICT)
		return -EINVAL;
	if (reg > NFT_REG_MAX)
		return -ERANGE;
	if (len == 0)
		return -EINVAL;
	if (len > FIELD_SIZEOF(struct nft_data, data))
		return -ERANGE;
	return 0;
}
EXPORT_SYMBOL_GPL(nft_validate_input_register);
EXPORT_SYMBOL_GPL(nft_validate_register_load);

/**
 *	nft_validate_register_store - validate an expressions' register store
+2 −3
Original line number Diff line number Diff line
@@ -64,9 +64,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
		return -EINVAL;

	priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
	err = nft_validate_input_register(priv->sreg);
	err = nft_validate_register_load(priv->sreg, priv->len);
	if (err < 0)
		return err;

+2 −5
Original line number Diff line number Diff line
@@ -96,10 +96,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
		return -EINVAL;
	}

	priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
	if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
		return -EINVAL;

	priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
	switch (priv->size) {
	case 2:
@@ -110,7 +106,8 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
	}

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
	err = nft_validate_input_register(priv->sreg);
	priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
	err = nft_validate_register_load(priv->sreg, priv->len);
	if (err < 0)
		return err;

+13 −12
Original line number Diff line number Diff line
@@ -75,12 +75,15 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
	struct nft_data_desc desc;
	int err;

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
	priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));

	err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
	BUG_ON(err < 0);

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
	err = nft_validate_register_load(priv->sreg, desc.len);
	if (err < 0)
		return err;

	priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
	priv->len = desc.len;
	return 0;
}
@@ -122,13 +125,17 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
	u32 mask;
	int err;

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));

	err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
	BUG_ON(err < 0);
	desc.len *= BITS_PER_BYTE;

	priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
	err = nft_validate_register_load(priv->sreg, desc.len);
	if (err < 0)
		return err;

	desc.len *= BITS_PER_BYTE;
	mask = nft_cmp_fast_mask(desc.len);

	priv->data = data.data[0] & mask;
	priv->len  = desc.len;
	return 0;
@@ -167,7 +174,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
{
	struct nft_data_desc desc;
	struct nft_data data;
	enum nft_registers sreg;
	enum nft_cmp_ops op;
	int err;

@@ -176,11 +182,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
	    tb[NFTA_CMP_DATA] == NULL)
		return ERR_PTR(-EINVAL);

	sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
	err = nft_validate_input_register(sreg);
	if (err < 0)
		return ERR_PTR(err);

	op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
	switch (op) {
	case NFT_CMP_EQ:
Loading