Blame SOURCES/0001-payload-check-icmp-dependency-before-removing-previo.patch

168a1c
From 9230899c6d2be8913646ff1a3b560865c330de7b Mon Sep 17 00:00:00 2001
168a1c
From: Florian Westphal <fw@strlen.de>
168a1c
Date: Mon, 1 Feb 2021 22:08:54 +0100
168a1c
Subject: [PATCH] payload: check icmp dependency before removing previous icmp
168a1c
 expression
168a1c
168a1c
nft is too greedy when removing icmp dependencies.
168a1c
'icmp code 1 type 2' did remove the type when printing.
168a1c
168a1c
Be more careful and check that the icmp type dependency of the
168a1c
candidate expression (earlier icmp payload expression) has the same
168a1c
type dependency as the new expression.
168a1c
168a1c
Reported-by: Eric Garver <eric@garver.life>
168a1c
Reported-by: Michael Biebl <biebl@debian.org>
168a1c
Tested-by: Eric Garver <eric@garver.life>
168a1c
Fixes: d0f3b9eaab8d77e ("payload: auto-remove simple icmp/icmpv6 dependency expressions")
168a1c
Signed-off-by: Florian Westphal <fw@strlen.de>
168a1c
(cherry picked from commit 533565244d88a818d8828ebabd7625e5a8a4c374)
168a1c
Signed-off-by: Phil Sutter <psutter@redhat.com>
168a1c
---
168a1c
 src/payload.c | 63 ++++++++++++++++++++++++++++++++++-----------------
168a1c
 1 file changed, 42 insertions(+), 21 deletions(-)
168a1c
168a1c
diff --git a/src/payload.c b/src/payload.c
168a1c
index 48529bcf5c514..a77ca55005509 100644
168a1c
--- a/src/payload.c
168a1c
+++ b/src/payload.c
168a1c
@@ -627,6 +627,40 @@ void payload_dependency_release(struct payload_dep_ctx *ctx)
168a1c
 	ctx->pdep  = NULL;
168a1c
 }
168a1c
 
168a1c
+static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
168a1c
+{
168a1c
+	switch (t) {
168a1c
+	case PROTO_ICMP_ANY:
168a1c
+		BUG("Invalid map for simple dependency");
168a1c
+	case PROTO_ICMP_ECHO: return ICMP_ECHO;
168a1c
+	case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST;
168a1c
+	case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH;
168a1c
+	case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT;
168a1c
+	case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG;
168a1c
+	case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY;
168a1c
+	case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB;
168a1c
+	}
168a1c
+
168a1c
+	BUG("Missing icmp type mapping");
168a1c
+}
168a1c
+
168a1c
+static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct expr *expr)
168a1c
+{
168a1c
+	const struct expr *dep = ctx->pdep->expr;
168a1c
+	uint8_t icmp_type;
168a1c
+
168a1c
+	icmp_type = expr->payload.tmpl->icmp_dep;
168a1c
+	if (icmp_type == PROTO_ICMP_ANY)
168a1c
+		return false;
168a1c
+
168a1c
+	if (dep->left->payload.desc != expr->payload.desc)
168a1c
+		return false;
168a1c
+
168a1c
+	icmp_type = icmp_dep_to_type(expr->payload.tmpl->icmp_dep);
168a1c
+
168a1c
+	return ctx->icmp_type == icmp_type;
168a1c
+}
168a1c
+
168a1c
 static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
168a1c
 					unsigned int family, struct expr *expr)
168a1c
 {
168a1c
@@ -661,6 +695,14 @@ static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
168a1c
 		break;
168a1c
 	}
168a1c
 
168a1c
+	if (expr->payload.base == PROTO_BASE_TRANSPORT_HDR &&
168a1c
+	    dep->left->payload.base == PROTO_BASE_TRANSPORT_HDR) {
168a1c
+		if (dep->left->payload.desc == &proto_icmp)
168a1c
+			return payload_may_dependency_kill_icmp(ctx, expr);
168a1c
+		if (dep->left->payload.desc == &proto_icmp6)
168a1c
+			return payload_may_dependency_kill_icmp(ctx, expr);
168a1c
+	}
168a1c
+
168a1c
 	return true;
168a1c
 }
168a1c
 
168a1c
@@ -680,10 +722,6 @@ void payload_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
168a1c
 	if (payload_dependency_exists(ctx, expr->payload.base) &&
168a1c
 	    payload_may_dependency_kill(ctx, family, expr))
168a1c
 		payload_dependency_release(ctx);
168a1c
-	else if (ctx->icmp_type && ctx->pdep) {
168a1c
-		fprintf(stderr, "Did not kill \n");
168a1c
-		payload_dependency_release(ctx);
168a1c
-	}
168a1c
 }
168a1c
 
168a1c
 void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
168a1c
@@ -707,23 +745,6 @@ void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr,
168a1c
 	}
168a1c
 }
168a1c
 
168a1c
-static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
168a1c
-{
168a1c
-	switch (t) {
168a1c
-	case PROTO_ICMP_ANY:
168a1c
-		BUG("Invalid map for simple dependency");
168a1c
-	case PROTO_ICMP_ECHO: return ICMP_ECHO;
168a1c
-	case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST;
168a1c
-	case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH;
168a1c
-	case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT;
168a1c
-	case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG;
168a1c
-	case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY;
168a1c
-	case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB;
168a1c
-	}
168a1c
-
168a1c
-	BUG("Missing icmp type mapping");
168a1c
-}
168a1c
-
168a1c
 /**
168a1c
  * payload_expr_complete - fill in type information of a raw payload expr
168a1c
  *
168a1c
-- 
168a1c
2.31.1
168a1c