nftables/0013-netlink_delinearize-postprocess-binary-ands-in-conca.patch
Phil Sutter 552075b562 nftables-1.0.4-8.el9
* Thu Feb 09 2023 Phil Sutter <psutter@redhat.com> [1.0.4-8.el9]
- monitor: Sanitize startup race condition (Phil Sutter) [2130721]
- evaluate: set eval ctx for add/update statements with integer constants (Phil Sutter) [2094894]
- src: allow anon set concatenation with ether and vlan (Phil Sutter) [2094887]
- evaluate: search stacked header list for matching payload dep (Phil Sutter) [2094887]
- netlink_delinearize: also postprocess OP_AND in set element context (Phil Sutter) [2094887]
- tests: add a test case for ether and vlan listing (Phil Sutter) [2094887]
- debug: dump the l2 protocol stack (Phil Sutter) [2094887]
- proto: track full stack of seen l2 protocols, not just cumulative offset (Phil Sutter) [2094887]
- netlink_delinearize: postprocess binary ands in concatenations (Phil Sutter) [2094887]
- netlink_delinearize: allow postprocessing on concatenated elements (Phil Sutter) [2094887]
- intervals: check for EXPR_F_REMOVE in case of element mismatch (Phil Sutter) [2115627]
- intervals: fix crash when trying to remove element in empty set (Phil Sutter) [2115627]
- scanner: don't pop active flex scanner scope (Phil Sutter) [2113874]
- parser: add missing synproxy scope closure (Phil Sutter) [2113874]
- tests/py: Add a test for failing ipsec after counter (Phil Sutter) [2113874]
- doc: Document limitations of ipsec expression with xfrm_interface (Phil Sutter) [1806431]
Resolves: rhbz#1806431, rhbz#2094887, rhbz#2094894, rhbz#2113874, rhbz#2115627, rhbz#2130721, rhbz#2094890
2023-02-09 15:47:30 +01:00

160 lines
5.0 KiB
Diff

From 29f041b93d7fc4e23c62c2e2e3cbbeaafa83b4ef Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Thu, 9 Feb 2023 10:27:57 +0100
Subject: [PATCH] netlink_delinearize: postprocess binary ands in
concatenations
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2094887
Upstream Status: nftables commit 89688c947efc3
commit 89688c947efc36d25c58c85650414fa3a491732e
Author: Florian Westphal <fw@strlen.de>
Date: Tue Jun 14 21:56:48 2022 +0200
netlink_delinearize: postprocess binary ands in concatenations
Input:
update ether saddr . vlan id timeout 5s @macset
ether saddr . vlan id @macset
Before this patch, gets rendered as:
update @macset { @ll,48,48 . @ll,112,16 & 0xfff timeout 5s }
@ll,48,48 . @ll,112,16 & 0xfff @macset
After this, listing will show:
update @macset { @ll,48,48 . vlan id timeout 5s }
@ll,48,48 . vlan id @macset
The @ll, ... is due to vlan description replacing the ethernet one,
so payload decode fails to take the concatenation apart (the ethernet
header payload info is matched vs. vlan template).
This will be adjusted by a followup patch.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
include/netlink.h | 6 ++++++
src/netlink_delinearize.c | 45 ++++++++++++++++++++++++++++++++++-----
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/include/netlink.h b/include/netlink.h
index e8e0f68..71c888f 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -42,10 +42,16 @@ struct netlink_parse_ctx {
struct netlink_ctx *nlctx;
};
+
+#define RULE_PP_IN_CONCATENATION (1 << 0)
+
+#define RULE_PP_REMOVE_OP_AND (RULE_PP_IN_CONCATENATION)
+
struct rule_pp_ctx {
struct proto_ctx pctx;
struct payload_dep_ctx pdctx;
struct stmt *stmt;
+ unsigned int flags;
};
extern const struct input_descriptor indesc_netlink;
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 2f13990..cba419d 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2259,12 +2259,13 @@ static void binop_adjust(const struct expr *binop, struct expr *right,
}
}
-static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
- struct expr **expr_binop)
+static void __binop_postprocess(struct rule_pp_ctx *ctx,
+ struct expr *expr,
+ struct expr *left,
+ struct expr *mask,
+ struct expr **expr_binop)
{
struct expr *binop = *expr_binop;
- struct expr *left = binop->left;
- struct expr *mask = binop->right;
unsigned int shift;
assert(binop->etype == EXPR_BINOP);
@@ -2300,15 +2301,26 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
assert(binop->left == left);
*expr_binop = expr_get(left);
- expr_free(binop);
if (left->etype == EXPR_PAYLOAD)
payload_match_postprocess(ctx, expr, left);
else if (left->etype == EXPR_EXTHDR && right)
expr_set_type(right, left->dtype, left->byteorder);
+
+ expr_free(binop);
}
}
+static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
+ struct expr **expr_binop)
+{
+ struct expr *binop = *expr_binop;
+ struct expr *left = binop->left;
+ struct expr *mask = binop->right;
+
+ __binop_postprocess(ctx, expr, left, mask, expr_binop);
+}
+
static void map_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
{
struct expr *binop = expr->map;
@@ -2541,6 +2553,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
LIST_HEAD(tmp);
struct expr *n;
+ ctx->flags |= RULE_PP_IN_CONCATENATION;
list_for_each_entry_safe(i, n, &expr->expressions, list) {
if (type) {
dtype = concat_subtype_lookup(type, --off);
@@ -2552,6 +2565,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
ntype = concat_subtype_add(ntype, i->dtype->type);
}
+ ctx->flags &= ~RULE_PP_IN_CONCATENATION;
list_splice(&tmp, &expr->expressions);
datatype_set(expr, concat_type_alloc(ntype));
break;
@@ -2568,6 +2582,27 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
expr_set_type(expr->right, &integer_type,
BYTEORDER_HOST_ENDIAN);
break;
+ case OP_AND:
+ expr_set_type(expr->right, expr->left->dtype,
+ expr->left->byteorder);
+
+ /* Do not process OP_AND in ordinary rule context.
+ *
+ * Removal needs to be performed as part of the relational
+ * operation because the RHS constant might need to be adjusted
+ * (shifted).
+ *
+ * This is different in set element context or concatenations:
+ * There is no relational operation (eq, neq and so on), thus
+ * it needs to be processed right away.
+ */
+ if ((ctx->flags & RULE_PP_REMOVE_OP_AND) &&
+ expr->left->etype == EXPR_PAYLOAD &&
+ expr->right->etype == EXPR_VALUE) {
+ __binop_postprocess(ctx, expr, expr->left, expr->right, exprp);
+ return;
+ }
+ break;
default:
expr_set_type(expr->right, expr->left->dtype,
expr->left->byteorder);
--
2.39.1