Commit 664899e8 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nftables: relax check for stateful expressions in set definition

Restore the original behaviour where users are allowed to add an element
with any stateful expression if the set definition specifies no stateful
expressions. Make sure upper maximum number of stateful expressions of
NFT_SET_EXPR_MAX is not reached.

Fixes: 8cfd9b0f ("netfilter: nftables: generalize set expressions support")
Fixes: 48b0ae04 ("netfilter: nftables: netlink support for several set element expressions")
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 07998281
...@@ -5281,6 +5281,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5281,6 +5281,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nft_expr *expr_array[NFT_SET_EXPR_MAX] = {}; struct nft_expr *expr_array[NFT_SET_EXPR_MAX] = {};
struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
u8 genmask = nft_genmask_next(ctx->net); u8 genmask = nft_genmask_next(ctx->net);
u32 flags = 0, size = 0, num_exprs = 0;
struct nft_set_ext_tmpl tmpl; struct nft_set_ext_tmpl tmpl;
struct nft_set_ext *ext, *ext2; struct nft_set_ext *ext, *ext2;
struct nft_set_elem elem; struct nft_set_elem elem;
...@@ -5290,7 +5291,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5290,7 +5291,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nft_data_desc desc; struct nft_data_desc desc;
enum nft_registers dreg; enum nft_registers dreg;
struct nft_trans *trans; struct nft_trans *trans;
u32 flags = 0, size = 0;
u64 timeout; u64 timeout;
u64 expiration; u64 expiration;
int err, i; int err, i;
...@@ -5356,7 +5356,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5356,7 +5356,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (nla[NFTA_SET_ELEM_EXPR]) { if (nla[NFTA_SET_ELEM_EXPR]) {
struct nft_expr *expr; struct nft_expr *expr;
if (set->num_exprs != 1) if (set->num_exprs && set->num_exprs != 1)
return -EOPNOTSUPP; return -EOPNOTSUPP;
expr = nft_set_elem_expr_alloc(ctx, set, expr = nft_set_elem_expr_alloc(ctx, set,
...@@ -5365,8 +5365,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5365,8 +5365,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
return PTR_ERR(expr); return PTR_ERR(expr);
expr_array[0] = expr; expr_array[0] = expr;
num_exprs = 1;
if (set->exprs[0] && set->exprs[0]->ops != expr->ops) { if (set->num_exprs && set->exprs[0]->ops != expr->ops) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_set_elem_expr; goto err_set_elem_expr;
} }
...@@ -5375,12 +5376,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5375,12 +5376,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nlattr *tmp; struct nlattr *tmp;
int left; int left;
if (set->num_exprs == 0)
return -EOPNOTSUPP;
i = 0; i = 0;
nla_for_each_nested(tmp, nla[NFTA_SET_ELEM_EXPRESSIONS], left) { nla_for_each_nested(tmp, nla[NFTA_SET_ELEM_EXPRESSIONS], left) {
if (i == set->num_exprs) { if (i == NFT_SET_EXPR_MAX ||
(set->num_exprs && set->num_exprs == i)) {
err = -E2BIG; err = -E2BIG;
goto err_set_elem_expr; goto err_set_elem_expr;
} }
...@@ -5394,14 +5393,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5394,14 +5393,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
goto err_set_elem_expr; goto err_set_elem_expr;
} }
expr_array[i] = expr; expr_array[i] = expr;
num_exprs++;
if (expr->ops != set->exprs[i]->ops) { if (set->num_exprs && expr->ops != set->exprs[i]->ops) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_set_elem_expr; goto err_set_elem_expr;
} }
i++; i++;
} }
if (set->num_exprs != i) { if (set->num_exprs && set->num_exprs != i) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_set_elem_expr; goto err_set_elem_expr;
} }
...@@ -5409,6 +5409,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5409,6 +5409,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
err = nft_set_elem_expr_clone(ctx, set, expr_array); err = nft_set_elem_expr_clone(ctx, set, expr_array);
if (err < 0) if (err < 0)
goto err_set_elem_expr_clone; goto err_set_elem_expr_clone;
num_exprs = set->num_exprs;
} }
err = nft_setelem_parse_key(ctx, set, &elem.key.val, err = nft_setelem_parse_key(ctx, set, &elem.key.val,
...@@ -5433,8 +5435,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5433,8 +5435,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT); nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
} }
if (set->num_exprs) { if (num_exprs) {
for (i = 0; i < set->num_exprs; i++) for (i = 0; i < num_exprs; i++)
size += expr_array[i]->ops->size; size += expr_array[i]->ops->size;
nft_set_ext_add_length(&tmpl, NFT_SET_EXT_EXPRESSIONS, nft_set_ext_add_length(&tmpl, NFT_SET_EXT_EXPRESSIONS,
...@@ -5522,7 +5524,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5522,7 +5524,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
*nft_set_ext_obj(ext) = obj; *nft_set_ext_obj(ext) = obj;
obj->use++; obj->use++;
} }
for (i = 0; i < set->num_exprs; i++) for (i = 0; i < num_exprs; i++)
nft_set_elem_expr_setup(ext, i, expr_array); nft_set_elem_expr_setup(ext, i, expr_array);
trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
...@@ -5584,7 +5586,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ...@@ -5584,7 +5586,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
err_parse_key: err_parse_key:
nft_data_release(&elem.key.val, NFT_DATA_VALUE); nft_data_release(&elem.key.val, NFT_DATA_VALUE);
err_set_elem_expr: err_set_elem_expr:
for (i = 0; i < set->num_exprs && expr_array[i]; i++) for (i = 0; i < num_exprs && expr_array[i]; i++)
nft_expr_destroy(ctx, expr_array[i]); nft_expr_destroy(ctx, expr_array[i]);
err_set_elem_expr_clone: err_set_elem_expr_clone:
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment