diff mbox series

[nft,09/15] netlink_delinearize: Fix for escaped asterisk strings on Big Endian

Message ID 20211124172251.11539-10-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show
Series Fix netlink debug output on Big Endian | expand

Commit Message

Phil Sutter Nov. 24, 2021, 5:22 p.m. UTC
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 <phil@nwl.cc>
---
 src/netlink_delinearize.c | 57 ++++++++++++---------------------------
 1 file changed, 17 insertions(+), 40 deletions(-)
diff mbox series

Patch

diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 0c2b439eac6fb..db58e8c386c00 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)