aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-04-10 21:27:38 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2015-04-13 11:17:30 -0400
commitd0a11fc3dc4ab4c717642c9c15c8ad1cbc00d2ec (patch)
treed3dca65a7ca6c2e95b11d9dd108bdeec660b957c
parent49499c3e6e18b7677a63316f3ff54a16533dc28f (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.h3
-rw-r--r--net/netfilter/nf_tables_api.c26
-rw-r--r--net/netfilter/nft_bitwise.c6
-rw-r--r--net/netfilter/nft_cmp.c9
-rw-r--r--net/netfilter/nft_immediate.c3
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
113int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 113int 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);
115void nft_data_uninit(const struct nft_data *data, enum nft_data_types type); 116void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
116int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, 117int 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
4342static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, 4345static 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
4365static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { 4369static 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 */
4385int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 4389int 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;