From f0f9cd656c005ba9a17cd3cef5769c285064b202 Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Fri, 16 Dec 2022 20:27:14 +0000 Subject: scanner: treat invalid octal strings as strings The action associated with the `{numberstring}` pattern, passes `yytext` to `strtoull` with base 0: errno = 0; yylval->val = strtoull(yytext, NULL, 0); if (errno != 0) { yylval->string = xstrdup(yytext); return STRING; } return NUM; If `yytext` begins with '0', it will be parsed as octal. However, this has unexpected consequences if the token contains non-octal characters. `09` will be parsed as 0; `0308` will be parsed as 24, because `strtoull` and its siblings stop parsing as soon as they reach a character in the input which is not valid for the base. Replace the `{numberstring}` match with separate `{hexstring}` and `{decstring}` matches. For `{decstring}` set the base to 8 if the leading character is '0', and handle an incompletely parsed token in the same way as one that causes `strtoull` to set `errno`. Thus, instead of: $ sudo nft -f - <<<' table x { chain y { ip saddr 0308 continue comment "parsed as 0.0.0.24/32" } } ' $ sudo nft list chain x y table ip x { chain y { ip saddr 0.0.0.24 continue comment "parsed as 0.0.0.24/32" } } We get: $ sudo ./src/nft -f - <<<' > table x { > chain y { > ip saddr 0308 continue comment "error" > } > } > ' /dev/stdin:4:14-17: Error: Could not resolve hostname: Name or service not known ip saddr 0308 continue comment "error" ^^^^ Add a test-case. Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=932880 Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1363 Signed-off-by: Jeremy Sowden Signed-off-by: Pablo Neira Ayuso --- tests/shell/testcases/parsing/octal | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 tests/shell/testcases/parsing/octal (limited to 'tests') diff --git a/tests/shell/testcases/parsing/octal b/tests/shell/testcases/parsing/octal new file mode 100755 index 00000000..09ac26e7 --- /dev/null +++ b/tests/shell/testcases/parsing/octal @@ -0,0 +1,13 @@ +#!/bin/bash + +$NFT add table t || exit 1 +$NFT add chain t c || exit 1 +$NFT add rule t c 'ip saddr 01 continue comment "0.0.0.1"' || exit 1 +$NFT add rule t c 'ip saddr 08 continue comment "error"' && { + echo "'"ip saddr 08"'" not rejected 1>&2 + exit 1 +} +$NFT delete table t || exit 1 + +exit 0 + -- cgit v1.2.3