|
|
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 |
|