summaryrefslogtreecommitdiffstats
path: root/net/netfilter/nf_tables_api.c
diff options
context:
space:
mode:
authorPatrick McHardy2015-04-11 03:27:26 +0200
committerPablo Neira Ayuso2015-04-13 16:25:49 +0200
commit45d9bcda21f4c13be75e3571b0f0ef39e77934b5 (patch)
tree54312412f1a9253360db901877e8b51991777562 /net/netfilter/nf_tables_api.c
parentMerge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsh... (diff)
downloadkernel-qcow2-linux-45d9bcda21f4c13be75e3571b0f0ef39e77934b5.tar.gz
kernel-qcow2-linux-45d9bcda21f4c13be75e3571b0f0ef39e77934b5.tar.xz
kernel-qcow2-linux-45d9bcda21f4c13be75e3571b0f0ef39e77934b5.zip
netfilter: nf_tables: validate len in nft_validate_data_load()
For values spanning multiple registers, we need to validate that enough space is available from the destination register onwards. Add a len argument to nft_validate_data_load() and consolidate the existing length validations in preparation of that. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nf_tables_api.c')
-rw-r--r--net/netfilter/nf_tables_api.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0b96fa0d64b2..564f9ed6680d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2799,7 +2799,8 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
dreg = nft_type_to_reg(set->dtype);
return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext),
set->dtype == NFT_DATA_VERDICT ?
- NFT_DATA_VERDICT : NFT_DATA_VALUE);
+ NFT_DATA_VERDICT : NFT_DATA_VALUE,
+ set->dlen);
}
int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
@@ -3334,7 +3335,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
continue;
err = nft_validate_data_load(&bind_ctx, dreg,
- &data, d2.type);
+ &data, d2.type, d2.len);
if (err < 0)
goto err3;
}
@@ -4162,15 +4163,16 @@ EXPORT_SYMBOL_GPL(nft_validate_output_register);
* @reg: the destination register number
* @data: the data to load
* @type: the data type
+ * @len: the length of the data
*
* Validate that a data load uses the appropriate data type for
- * the destination register. A value of NULL for the data means
- * that its runtime gathered data, which is always of type
- * NFT_DATA_VALUE.
+ * the destination register and the length is within the bounds.
+ * A value of NULL for the data means that its runtime gathered
+ * data, which is always of type NFT_DATA_VALUE.
*/
int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
const struct nft_data *data,
- enum nft_data_types type)
+ enum nft_data_types type, unsigned int len)
{
int err;
@@ -4193,6 +4195,10 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
return 0;
default:
+ if (len == 0)
+ return -EINVAL;
+ if (len > FIELD_SIZEOF(struct nft_data, data))
+ return -ERANGE;
if (data != NULL && type != NFT_DATA_VALUE)
return -EINVAL;
return 0;