]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
rule: fix ASAN errors in chain priority to textual names
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 29 Feb 2024 15:50:37 +0000 (16:50 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 5 Mar 2024 17:41:06 +0000 (18:41 +0100)
ASAN reports several errors when listing this ruleset:

 table ip x {
        chain y {
                type filter hook input priority -2147483648; policy accept;
        }
 }

src/rule.c:1002:8: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
src/rule.c:1001:11: runtime error: signed integer overflow: -2147483648 - 50 cannot be represented in type 'int'

Use int64_t for the offset to avoid an underflow when calculating
closest existing priority definition.

Use llabs() because abs() is undefined with INT32_MIN.

Fixes: c8a0e8c90e2d ("src: Set/print standard chain prios with textual names")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/rule.c

index 342c43fb1b4b23737eae5ccd33b9c4748561a0d5..adab584e9a792168c026d4a4b48ca946dc0cb33b 100644 (file)
@@ -977,10 +977,11 @@ static const char *prio2str(const struct output_ctx *octx,
                            const struct expr *expr)
 {
        const struct prio_tag *prio_arr;
-       int std_prio, offset, prio;
+       const uint32_t reach = 10;
        const char *std_prio_str;
-       const int reach = 10;
+       int std_prio, prio;
        size_t i, arr_size;
+       int64_t offset;
 
        mpz_export_data(&prio, expr->value, BYTEORDER_HOST_ENDIAN, sizeof(int));
        if (family == NFPROTO_BRIDGE) {
@@ -995,19 +996,21 @@ static const char *prio2str(const struct output_ctx *octx,
                for (i = 0; i < arr_size; ++i) {
                        std_prio = prio_arr[i].val;
                        std_prio_str = prio_arr[i].str;
-                       if (abs(prio - std_prio) <= reach) {
+
+                       offset = (int64_t)prio - std_prio;
+                       if (llabs(offset) <= reach) {
                                if (!std_prio_family_hook_compat(std_prio,
                                                                 family, hook))
                                        break;
-                               offset = prio - std_prio;
+
                                strncpy(buf, std_prio_str, bufsize);
                                if (offset > 0)
                                        snprintf(buf + strlen(buf),
-                                                bufsize - strlen(buf), " + %d",
+                                                bufsize - strlen(buf), " + %" PRIu64,
                                                 offset);
                                else if (offset < 0)
                                        snprintf(buf + strlen(buf),
-                                                bufsize - strlen(buf), " - %d",
+                                                bufsize - strlen(buf), " - %" PRIu64,
                                                 -offset);
                                return buf;
                        }