]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: do not assert when value exceeds expected width
authorFlorian Westphal <fw@strlen.de>
Fri, 22 Dec 2023 14:30:09 +0000 (15:30 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 22 Jan 2025 23:41:53 +0000 (00:41 +0100)
commit a852022d719e5a414df41a10c331f4492e9d3073 upstream.

Inputs:
ip protocol . th dport { tcp / 22,  }'
or
th dport . ip protocol { tcp / 22,  }'

are not rejected at this time. 'list ruleset' yields:
 ip protocol & nft: src/gmputil.c:77: mpz_get_uint8: Assertion `cnt <= 1' failed.
or
 th dport & nft: src/gmputil.c:87: mpz_get_be16: Assertion `cnt <= 1' failed.

While this should be caught at input too, the print path should be more
robust, e.g. when there are direct nfnetlink users.

After this patch, the print functions fall back to
'integer_type_print' which can handle large numbers too.

Note that the output printed this way cannot be read back by nft;
it will dump something like:

  tcp dport & 18446739675663040512 . ip protocol 0 . 0

but thats better than assert().

v2: same problem exists for service too.

Signed-off-by: Florian Westphal <fw@strlen.de>
src/datatype.c

index 675faa08c2cc8e976a7ff41a0c1c4df8ae4c600c..fa279a5a0013ecfba231a3a2dba14407c47b3a0e 100644 (file)
@@ -618,7 +618,8 @@ static void inet_protocol_type_print(const struct expr *expr,
 {
        struct protoent *p;
 
-       if (!nft_output_numeric_proto(octx)) {
+       if (!nft_output_numeric_proto(octx) &&
+           mpz_cmp_ui(expr->value, UINT8_MAX) <= 0) {
                p = getprotobynumber(mpz_get_uint8(expr->value));
                if (p != NULL) {
                        nft_print(octx, "%s", p->p_name);
@@ -697,7 +698,8 @@ static void inet_service_print(const struct expr *expr, struct output_ctx *octx)
 
 void inet_service_type_print(const struct expr *expr, struct output_ctx *octx)
 {
-       if (nft_output_service(octx)) {
+       if (nft_output_service(octx) &&
+           mpz_cmp_ui(expr->value, UINT16_MAX) <= 0) {
                inet_service_print(expr, octx);
                return;
        }