diff mbox series

[nft] rule: fix ASAN errors in priority to string conversion

Message ID 20240229161408.194625-1-pablo@netfilter.org
State Accepted
Headers show
Series [nft] rule: fix ASAN errors in priority to string conversion | expand

Commit Message

Pablo Neira Ayuso Feb. 29, 2024, 4:14 p.m. UTC
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 | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/src/rule.c b/src/rule.c
index 342c43fb1b4b..adab584e9a79 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -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;
 			}