summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2020-04-13 21:48:03 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2020-04-14 23:15:05 +0200
commit09441b5e92ceea60198a35cd657904fa7a10ee54 (patch)
treed9415672468d26b87d860347ed702b067cba8272 /src/evaluate.c
parentf1e5a0499c0773f18bc592dd0da0340120daa482 (diff)
src: Set NFT_SET_CONCAT flag for sets with concatenated ranges
Pablo reports that nft, after commit 8ac2f3b2fca3 ("src: Add support for concatenated set ranges"), crashes with older kernels (< 5.6) without support for concatenated set ranges: those sets will be sent to the kernel, which adds them without notion of the fact that different concatenated fields are actually included, and nft crashes while trying to list this kind of malformed concatenation. Use the NFT_SET_CONCAT flag introduced by kernel commit ef516e8625dd ("netfilter: nf_tables: reintroduce the NFT_SET_CONCAT flag") when sets including concatenated ranges are sent to the kernel, so that older kernels (with no knowledge of this flag itself) will refuse set creation. Note that, in expr_evaluate_set(), we have to check for the presence of the flag, also on empty sets that might carry it in context data, and actually set it in the actual set flags. Reported-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index fcc79386..759b1736 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1382,10 +1382,16 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr)
set->size += i->size - 1;
set->set_flags |= i->set_flags;
expr_free(i);
- } else if (!expr_is_singleton(i))
+ } else if (!expr_is_singleton(i)) {
set->set_flags |= NFT_SET_INTERVAL;
+ if (i->key->etype == EXPR_CONCAT)
+ set->set_flags |= NFT_SET_CONCAT;
+ }
}
+ if (ctx->set && (ctx->set->flags & NFT_SET_CONCAT))
+ set->set_flags |= NFT_SET_CONCAT;
+
set->set_flags |= NFT_SET_CONSTANT;
datatype_set(set, ctx->ectx.dtype);
@@ -3463,6 +3469,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
memcpy(&set->desc.field_len, &set->key->field_len,
sizeof(set->desc.field_len));
set->desc.field_count = set->key->field_count;
+ set->flags |= NFT_SET_CONCAT;
}
if (set_is_datamap(set->flags)) {