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; |