diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-11-09 15:47:37 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-11-11 13:35:00 +0100 |
commit | 2f16228172ff3629c09b7d0633e30c125aebc37e (patch) | |
tree | 2501226979b34ca2c74529afcfb50d0ce9ff02ba /src/evaluate.c | |
parent | 8ac986f862040a331e57984ad705a54e9c09417b (diff) |
evaluate: fix string matching on big endian
We need to reallocate the constant expression with the right expression
length when evaluating the string. Otherwise the linearization step
generates a wrong comparison on big endian. We cannot do this any
earlier since we don't know the maximum string length for this datatype
at the parsing stage.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 78424715..48f071f7 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -208,7 +208,8 @@ static int expr_evaluate_string(struct eval_ctx *ctx, struct expr **exprp) struct expr *expr = *exprp; unsigned int len = div_round_up(expr->len, BITS_PER_BYTE), datalen; struct expr *value, *prefix; - char data[len + 1]; + int data_len = ctx->ectx.len > 0 ? ctx->ectx.len : len + 1; + char data[data_len]; if (ctx->ectx.len > 0) { if (expr->len > ctx->ectx.len) @@ -218,15 +219,25 @@ static int expr_evaluate_string(struct eval_ctx *ctx, struct expr **exprp) expr->len = ctx->ectx.len; } + memset(data + len, 0, data_len - len); mpz_export_data(data, expr->value, BYTEORDER_HOST_ENDIAN, len); datalen = strlen(data) - 1; - if (data[datalen] != '*') + if (data[datalen] != '*') { + /* We need to reallocate the constant expression with the right + * expression length to avoid problems on big endian. + */ + value = constant_expr_alloc(&expr->location, &string_type, + BYTEORDER_HOST_ENDIAN, + expr->len, data); + expr_free(expr); + *exprp = value; return 0; + } if (datalen - 1 >= 0 && data[datalen - 1] == '\\') { - char unescaped_str[len]; + char unescaped_str[data_len]; memset(unescaped_str, 0, sizeof(unescaped_str)); xstrunescape(data, unescaped_str); |