From 4788869a3346b5b3f1f6a3cdb12fdf79da961ef9 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 10 Mar 2021 19:46:08 +0100 Subject: netlink_delinearize: Fix for escaped asterisk strings on Big Endian The original nul-char detection was not functional on Big Endian. Instead, go a simpler route by exporting the string and working on the exported data to check for a nul-char and escape a trailing asterisk if present. With the data export already happening in the caller, fold escaped_string_wildcard_expr_alloc() into it as well. Fixes: b851ba4731d9f ("src: add interface wildcard matching") Signed-off-by: Phil Sutter --- src/netlink_delinearize.c | 57 ++++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 40 deletions(-) (limited to 'src/netlink_delinearize.c') diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 0c2b439e..db58e8c3 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2422,56 +2422,33 @@ static struct expr *string_wildcard_expr_alloc(struct location *loc, expr->len + BITS_PER_BYTE, data); } -static void escaped_string_wildcard_expr_alloc(struct expr **exprp, - unsigned int len) -{ - struct expr *expr = *exprp, *tmp; - char data[len + 3]; - int pos; - - mpz_export_data(data, expr->value, BYTEORDER_HOST_ENDIAN, len); - pos = div_round_up(len, BITS_PER_BYTE); - data[pos - 1] = '\\'; - data[pos] = '*'; - - tmp = constant_expr_alloc(&expr->location, expr->dtype, - BYTEORDER_HOST_ENDIAN, - expr->len + BITS_PER_BYTE, data); - expr_free(expr); - *exprp = tmp; -} - /* This calculates the string length and checks if it is nul-terminated, this * function is quite a hack :) */ static bool __expr_postprocess_string(struct expr **exprp) { struct expr *expr = *exprp; - unsigned int len = expr->len; - bool nulterminated = false; - mpz_t tmp; - - mpz_init(tmp); - while (len >= BITS_PER_BYTE) { - mpz_bitmask(tmp, BITS_PER_BYTE); - mpz_lshift_ui(tmp, len - BITS_PER_BYTE); - mpz_and(tmp, tmp, expr->value); - if (mpz_cmp_ui(tmp, 0)) - break; - else - nulterminated = true; - len -= BITS_PER_BYTE; - } + unsigned int len = div_round_up(expr->len, BITS_PER_BYTE); + char data[len + 1]; - mpz_rshift_ui(tmp, len - BITS_PER_BYTE); + mpz_export_data(data, expr->value, BYTEORDER_HOST_ENDIAN, len); - if (nulterminated && - mpz_cmp_ui(tmp, '*') == 0) - escaped_string_wildcard_expr_alloc(exprp, len); + if (data[len - 1] != '\0') + return false; - mpz_clear(tmp); + len = strlen(data); + if (len && data[len - 1] == '*') { + data[len - 1] = '\\'; + data[len] = '*'; + data[len + 1] = '\0'; + expr = constant_expr_alloc(&expr->location, expr->dtype, + BYTEORDER_HOST_ENDIAN, + (len + 2) * BITS_PER_BYTE, data); + expr_free(*exprp); + *exprp = expr; + } - return nulterminated; + return true; } static struct expr *expr_postprocess_string(struct expr *expr) -- cgit v1.2.3