]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: clamp boolean value to 0 and 1
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 31 Jan 2025 11:54:32 +0000 (12:54 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 7 Feb 2025 10:53:32 +0000 (11:53 +0100)
If user provides a numeric value larger than 0 or 1, match never
happens:

 # nft --debug=netlink add rule x y tcp option sack-perm 4
 ip x y
  [ exthdr load tcpopt 1b @ 4 + 0 present => reg 1 ]
  [ cmp eq reg 1 0x00000004 ]

After this update:

 # nft --debug=netlink add rule x y tcp option sack-perm 4
 ip x y
  [ exthdr load tcpopt 1b @ 4 + 0 present => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]

This is to address a rare corner case, in case user specifies the
boolean value through the integer base type.

Fixes: 9fd9baba43c8 ("Introduce boolean datatype and boolean expression")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/datatype.c

index 0c13bbd4270e7a3e9810cbc29c23d310b9f05cf2..f347010f4a1af8c6ce556c1e1f418dd1dfadacbb 100644 (file)
@@ -1554,11 +1554,35 @@ static const struct symbol_table boolean_tbl = {
        },
 };
 
+static struct error_record *boolean_type_parse(struct parse_ctx *ctx,
+                                              const struct expr *sym,
+                                              struct expr **res)
+{
+       struct error_record *erec;
+       int num;
+
+       erec = integer_type_parse(ctx, sym, res);
+       if (erec)
+               return erec;
+
+       if (mpz_cmp_ui((*res)->value, 0))
+               num = 1;
+       else
+               num = 0;
+
+       expr_free(*res);
+
+       *res = constant_expr_alloc(&sym->location, &boolean_type,
+                                  BYTEORDER_HOST_ENDIAN, 1, &num);
+       return NULL;
+}
+
 const struct datatype boolean_type = {
        .type           = TYPE_BOOLEAN,
        .name           = "boolean",
        .desc           = "boolean type",
        .size           = 1,
+       .parse          = boolean_type_parse,
        .basetype       = &integer_type,
        .sym_tbl        = &boolean_tbl,
        .json           = boolean_type_json,