diff options
| author | Patrick McHardy <kaber@trash.net> | 2015-04-10 21:27:38 -0400 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-04-13 11:17:30 -0400 |
| commit | d0a11fc3dc4ab4c717642c9c15c8ad1cbc00d2ec (patch) | |
| tree | d3dca65a7ca6c2e95b11d9dd108bdeec660b957c | |
| parent | 49499c3e6e18b7677a63316f3ff54a16533dc28f (diff) | |
netfilter: nf_tables: support variable sized data in nft_data_init()
Add a size argument to nft_data_init() and pass in the available space.
This will be used by the following patches to support variable sized
set element data.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
| -rw-r--r-- | include/net/netfilter/nf_tables.h | 3 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 26 | ||||
| -rw-r--r-- | net/netfilter/nft_bitwise.c | 6 | ||||
| -rw-r--r-- | net/netfilter/nft_cmp.c | 9 | ||||
| -rw-r--r-- | net/netfilter/nft_immediate.c | 3 |
5 files changed, 30 insertions, 17 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 1f9b848c778c..160577bf0f0a 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h | |||
| @@ -110,7 +110,8 @@ struct nft_data_desc { | |||
| 110 | unsigned int len; | 110 | unsigned int len; |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, | 113 | int nft_data_init(const struct nft_ctx *ctx, |
| 114 | struct nft_data *data, unsigned int size, | ||
| 114 | struct nft_data_desc *desc, const struct nlattr *nla); | 115 | struct nft_data_desc *desc, const struct nlattr *nla); |
| 115 | void nft_data_uninit(const struct nft_data *data, enum nft_data_types type); | 116 | void nft_data_uninit(const struct nft_data *data, enum nft_data_types type); |
| 116 | int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, | 117 | int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 03faf76ce3b8..2b3f88f4c70f 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -3299,7 +3299,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, | |||
| 3299 | timeout = set->timeout; | 3299 | timeout = set->timeout; |
| 3300 | } | 3300 | } |
| 3301 | 3301 | ||
| 3302 | err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]); | 3302 | err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &d1, |
| 3303 | nla[NFTA_SET_ELEM_KEY]); | ||
| 3303 | if (err < 0) | 3304 | if (err < 0) |
| 3304 | goto err1; | 3305 | goto err1; |
| 3305 | err = -EINVAL; | 3306 | err = -EINVAL; |
| @@ -3314,7 +3315,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, | |||
| 3314 | } | 3315 | } |
| 3315 | 3316 | ||
| 3316 | if (nla[NFTA_SET_ELEM_DATA] != NULL) { | 3317 | if (nla[NFTA_SET_ELEM_DATA] != NULL) { |
| 3317 | err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]); | 3318 | err = nft_data_init(ctx, &data, sizeof(data), &d2, |
| 3319 | nla[NFTA_SET_ELEM_DATA]); | ||
| 3318 | if (err < 0) | 3320 | if (err < 0) |
| 3319 | goto err2; | 3321 | goto err2; |
| 3320 | 3322 | ||
| @@ -3458,7 +3460,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, | |||
| 3458 | if (nla[NFTA_SET_ELEM_KEY] == NULL) | 3460 | if (nla[NFTA_SET_ELEM_KEY] == NULL) |
| 3459 | goto err1; | 3461 | goto err1; |
| 3460 | 3462 | ||
| 3461 | err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]); | 3463 | err = nft_data_init(ctx, &elem.key, sizeof(elem.key), &desc, |
| 3464 | nla[NFTA_SET_ELEM_KEY]); | ||
| 3462 | if (err < 0) | 3465 | if (err < 0) |
| 3463 | goto err1; | 3466 | goto err1; |
| 3464 | 3467 | ||
| @@ -4339,7 +4342,8 @@ nla_put_failure: | |||
| 4339 | return -1; | 4342 | return -1; |
| 4340 | } | 4343 | } |
| 4341 | 4344 | ||
| 4342 | static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, | 4345 | static int nft_value_init(const struct nft_ctx *ctx, |
| 4346 | struct nft_data *data, unsigned int size, | ||
| 4343 | struct nft_data_desc *desc, const struct nlattr *nla) | 4347 | struct nft_data_desc *desc, const struct nlattr *nla) |
| 4344 | { | 4348 | { |
| 4345 | unsigned int len; | 4349 | unsigned int len; |
| @@ -4347,10 +4351,10 @@ static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
| 4347 | len = nla_len(nla); | 4351 | len = nla_len(nla); |
| 4348 | if (len == 0) | 4352 | if (len == 0) |
| 4349 | return -EINVAL; | 4353 | return -EINVAL; |
| 4350 | if (len > sizeof(data->data)) | 4354 | if (len > size) |
| 4351 | return -EOVERFLOW; | 4355 | return -EOVERFLOW; |
| 4352 | 4356 | ||
| 4353 | nla_memcpy(data->data, nla, sizeof(data->data)); | 4357 | nla_memcpy(data->data, nla, len); |
| 4354 | desc->type = NFT_DATA_VALUE; | 4358 | desc->type = NFT_DATA_VALUE; |
| 4355 | desc->len = len; | 4359 | desc->len = len; |
| 4356 | return 0; | 4360 | return 0; |
| @@ -4363,8 +4367,7 @@ static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data, | |||
| 4363 | } | 4367 | } |
| 4364 | 4368 | ||
| 4365 | static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { | 4369 | static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { |
| 4366 | [NFTA_DATA_VALUE] = { .type = NLA_BINARY, | 4370 | [NFTA_DATA_VALUE] = { .type = NLA_BINARY }, |
| 4367 | .len = FIELD_SIZEOF(struct nft_data, data) }, | ||
| 4368 | [NFTA_DATA_VERDICT] = { .type = NLA_NESTED }, | 4371 | [NFTA_DATA_VERDICT] = { .type = NLA_NESTED }, |
| 4369 | }; | 4372 | }; |
| 4370 | 4373 | ||
| @@ -4373,6 +4376,7 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { | |||
| 4373 | * | 4376 | * |
| 4374 | * @ctx: context of the expression using the data | 4377 | * @ctx: context of the expression using the data |
| 4375 | * @data: destination struct nft_data | 4378 | * @data: destination struct nft_data |
| 4379 | * @size: maximum data length | ||
| 4376 | * @desc: data description | 4380 | * @desc: data description |
| 4377 | * @nla: netlink attribute containing data | 4381 | * @nla: netlink attribute containing data |
| 4378 | * | 4382 | * |
| @@ -4382,7 +4386,8 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { | |||
| 4382 | * The caller can indicate that it only wants to accept data of type | 4386 | * The caller can indicate that it only wants to accept data of type |
| 4383 | * NFT_DATA_VALUE by passing NULL for the ctx argument. | 4387 | * NFT_DATA_VALUE by passing NULL for the ctx argument. |
| 4384 | */ | 4388 | */ |
| 4385 | int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, | 4389 | int nft_data_init(const struct nft_ctx *ctx, |
| 4390 | struct nft_data *data, unsigned int size, | ||
| 4386 | struct nft_data_desc *desc, const struct nlattr *nla) | 4391 | struct nft_data_desc *desc, const struct nlattr *nla) |
| 4387 | { | 4392 | { |
| 4388 | struct nlattr *tb[NFTA_DATA_MAX + 1]; | 4393 | struct nlattr *tb[NFTA_DATA_MAX + 1]; |
| @@ -4393,7 +4398,8 @@ int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, | |||
| 4393 | return err; | 4398 | return err; |
| 4394 | 4399 | ||
| 4395 | if (tb[NFTA_DATA_VALUE]) | 4400 | if (tb[NFTA_DATA_VALUE]) |
| 4396 | return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]); | 4401 | return nft_value_init(ctx, data, size, desc, |
| 4402 | tb[NFTA_DATA_VALUE]); | ||
| 4397 | if (tb[NFTA_DATA_VERDICT] && ctx != NULL) | 4403 | if (tb[NFTA_DATA_VERDICT] && ctx != NULL) |
| 4398 | return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); | 4404 | return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); |
| 4399 | return -EINVAL; | 4405 | return -EINVAL; |
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c index f1a9be2aecd1..d71cc18fa35d 100644 --- a/net/netfilter/nft_bitwise.c +++ b/net/netfilter/nft_bitwise.c | |||
| @@ -73,13 +73,15 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, | |||
| 73 | if (err < 0) | 73 | if (err < 0) |
| 74 | return err; | 74 | return err; |
| 75 | 75 | ||
| 76 | err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]); | 76 | err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1, |
| 77 | tb[NFTA_BITWISE_MASK]); | ||
| 77 | if (err < 0) | 78 | if (err < 0) |
| 78 | return err; | 79 | return err; |
| 79 | if (d1.len != priv->len) | 80 | if (d1.len != priv->len) |
| 80 | return -EINVAL; | 81 | return -EINVAL; |
| 81 | 82 | ||
| 82 | err = nft_data_init(NULL, &priv->xor, &d2, tb[NFTA_BITWISE_XOR]); | 83 | err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2, |
| 84 | tb[NFTA_BITWISE_XOR]); | ||
| 83 | if (err < 0) | 85 | if (err < 0) |
| 84 | return err; | 86 | return err; |
| 85 | if (d2.len != priv->len) | 87 | if (d2.len != priv->len) |
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c index ffaf214dd256..e25b35d70e4d 100644 --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c | |||
| @@ -75,7 +75,8 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 75 | struct nft_data_desc desc; | 75 | struct nft_data_desc desc; |
| 76 | int err; | 76 | int err; |
| 77 | 77 | ||
| 78 | err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]); | 78 | err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc, |
| 79 | tb[NFTA_CMP_DATA]); | ||
| 79 | BUG_ON(err < 0); | 80 | BUG_ON(err < 0); |
| 80 | 81 | ||
| 81 | priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); | 82 | priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); |
| @@ -125,7 +126,8 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, | |||
| 125 | u32 mask; | 126 | u32 mask; |
| 126 | int err; | 127 | int err; |
| 127 | 128 | ||
| 128 | err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); | 129 | err = nft_data_init(NULL, &data, sizeof(data), &desc, |
| 130 | tb[NFTA_CMP_DATA]); | ||
| 129 | BUG_ON(err < 0); | 131 | BUG_ON(err < 0); |
| 130 | 132 | ||
| 131 | priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); | 133 | priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); |
| @@ -195,7 +197,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[]) | |||
| 195 | return ERR_PTR(-EINVAL); | 197 | return ERR_PTR(-EINVAL); |
| 196 | } | 198 | } |
| 197 | 199 | ||
| 198 | err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); | 200 | err = nft_data_init(NULL, &data, sizeof(data), &desc, |
| 201 | tb[NFTA_CMP_DATA]); | ||
| 199 | if (err < 0) | 202 | if (err < 0) |
| 200 | return ERR_PTR(err); | 203 | return ERR_PTR(err); |
| 201 | 204 | ||
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c index 1e8e412eadae..db3b746858e3 100644 --- a/net/netfilter/nft_immediate.c +++ b/net/netfilter/nft_immediate.c | |||
| @@ -49,7 +49,8 @@ static int nft_immediate_init(const struct nft_ctx *ctx, | |||
| 49 | tb[NFTA_IMMEDIATE_DATA] == NULL) | 49 | tb[NFTA_IMMEDIATE_DATA] == NULL) |
| 50 | return -EINVAL; | 50 | return -EINVAL; |
| 51 | 51 | ||
| 52 | err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]); | 52 | err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc, |
| 53 | tb[NFTA_IMMEDIATE_DATA]); | ||
| 53 | if (err < 0) | 54 | if (err < 0) |
| 54 | return err; | 55 | return err; |
| 55 | priv->dlen = desc.len; | 56 | priv->dlen = desc.len; |
