backport upstream patches
(cherry picked from commit 0e6a0d500c190abf447a7169f540e88d79fd5f7f)
This commit is contained in:
parent
80b0f19fe0
commit
fdda182ca0
@ -0,0 +1,31 @@
|
|||||||
|
From f6b579344eee17e5587b6a7fcc444fe997cd8cb6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Maks Mishin <maks.mishinfz@gmail.com>
|
||||||
|
Date: Wed, 15 May 2024 23:25:03 +0300
|
||||||
|
Subject: [PATCH] evaluate: Fix incorrect checking the `base` variable in case
|
||||||
|
of IPV6
|
||||||
|
|
||||||
|
Found by RASU JSC.
|
||||||
|
|
||||||
|
Fixes: 2b29ea5f3c3e ("src: ct: add eval part to inject dependencies for ct saddr/daddr")
|
||||||
|
Signed-off-by: Maks Mishin <maks.mishinFZ@gmail.com>
|
||||||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
---
|
||||||
|
src/evaluate.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 8ab0c9e2..227f5da8 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -1126,7 +1126,7 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct)
|
||||||
|
base = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
|
||||||
|
if (base == &proto_ip)
|
||||||
|
ct->ct.nfproto = NFPROTO_IPV4;
|
||||||
|
- else if (base == &proto_ip)
|
||||||
|
+ else if (base == &proto_ip6)
|
||||||
|
ct->ct.nfproto = NFPROTO_IPV6;
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
62
backport-evaluate-disable-meta-set-with-ranges.patch
Normal file
62
backport-evaluate-disable-meta-set-with-ranges.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
From d99b44adc5cfc455fdafd9b4bdabd413edf9a38a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Mon, 4 Dec 2023 19:04:58 +0100
|
||||||
|
Subject: [PATCH] evaluate: disable meta set with ranges
|
||||||
|
|
||||||
|
... this will cause an assertion in netlink linearization, catch this
|
||||||
|
at eval stage instead.
|
||||||
|
|
||||||
|
before:
|
||||||
|
BUG: unknown expression type range
|
||||||
|
nft: netlink_linearize.c:908: netlink_gen_expr: Assertion `0' failed.
|
||||||
|
|
||||||
|
after:
|
||||||
|
/unknown_expr_type_range_assert:3:31-40: Error: Meta expression cannot be a range
|
||||||
|
meta mark set 0x001-3434
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
src/evaluate.c | 13 +++++++++++++
|
||||||
|
.../bogons/nft-f/unknown_expr_type_range_assert | 5 +++++
|
||||||
|
2 files changed, 18 insertions(+)
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/unknown_expr_type_range_assert
|
||||||
|
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 51ae276a..131b0a0e 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -3169,6 +3169,19 @@ static int stmt_evaluate_meta(struct eval_ctx *ctx, struct stmt *stmt)
|
||||||
|
&stmt->meta.expr);
|
||||||
|
ctx->stmt_len = 0;
|
||||||
|
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ switch (stmt->meta.expr->etype) {
|
||||||
|
+ case EXPR_RANGE:
|
||||||
|
+ ret = expr_error(ctx->msgs, stmt->meta.expr,
|
||||||
|
+ "Meta expression cannot be a range");
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/unknown_expr_type_range_assert b/tests/shell/testcases/bogons/nft-f/unknown_expr_type_range_assert
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..234dd623
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/unknown_expr_type_range_assert
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+table ip x {
|
||||||
|
+ chain k {
|
||||||
|
+ meta mark set 0x001-3434
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
From b626c86abaf294fcf1ec788f722071dc90da68c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Fri, 15 Dec 2023 10:19:02 +0100
|
||||||
|
Subject: [PATCH] evaluate: fix stack overflow with huge priority string
|
||||||
|
|
||||||
|
Alternative would be to refactor this and move this into the parsers
|
||||||
|
(bison, json) instead of this hidden re-parsing.
|
||||||
|
|
||||||
|
Fixes: 627c451b2351 ("src: allow variables in the chain priority specification")
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
src/evaluate.c | 2 +-
|
||||||
|
tests/shell/testcases/bogons/nft-f/huge_chain_prio | 5 +++++
|
||||||
|
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/huge_chain_prio
|
||||||
|
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 87cd68d3..5ddbde42 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -4897,7 +4897,7 @@ static bool evaluate_priority(struct eval_ctx *ctx, struct prio_spec *prio,
|
||||||
|
NFT_NAME_MAXLEN);
|
||||||
|
loc = prio->expr->location;
|
||||||
|
|
||||||
|
- if (sscanf(prio_str, "%s %c %d", prio_fst, &op, &prio_snd) < 3) {
|
||||||
|
+ if (sscanf(prio_str, "%255s %c %d", prio_fst, &op, &prio_snd) < 3) {
|
||||||
|
priority = std_prio_lookup(prio_str, family, hook);
|
||||||
|
if (priority == NF_IP_PRI_LAST)
|
||||||
|
return false;
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/huge_chain_prio b/tests/shell/testcases/bogons/nft-f/huge_chain_prio
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..41f8061a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/huge_chain_prio
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+table t {
|
||||||
|
+ chain c {
|
||||||
|
+ type filter hook input priority srcnDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD; policy accept;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
From 52a7af9bec15a4fb4bfea86e40b70f96098f7dfd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeremy Sowden <jeremy@azazel.net>
|
||||||
|
Date: Mon, 29 Apr 2024 20:27:52 +0100
|
||||||
|
Subject: [PATCH] evaluate: handle invalid mapping expressions in stateful
|
||||||
|
object statements gracefully.
|
||||||
|
|
||||||
|
Currently, they are reported as assertion failures:
|
||||||
|
|
||||||
|
BUG: invalid mapping expression variable
|
||||||
|
nft: src/evaluate.c:4618: stmt_evaluate_objref_map: Assertion `0' failed.
|
||||||
|
Aborted
|
||||||
|
|
||||||
|
Instead, report them more informatively as errors:
|
||||||
|
|
||||||
|
/space/azazel/tmp/ruleset.1067161.nft:15:29-38: Error: invalid mapping expression variable
|
||||||
|
quota name ip saddr map $quota_map
|
||||||
|
~~~~~~~~ ^^^^^^^^^^
|
||||||
|
|
||||||
|
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
|
||||||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
---
|
||||||
|
src/evaluate.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 1682ba58..f28ef2aa 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -4615,8 +4615,9 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||||
|
"Expression is not a map with objects");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- BUG("invalid mapping expression %s\n",
|
||||||
|
- expr_name(map->mappings));
|
||||||
|
+ return expr_binary_error(ctx->msgs, map->mappings, map->map,
|
||||||
|
+ "invalid mapping expression %s",
|
||||||
|
+ expr_name(map->mappings));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!datatype_equal(map->map->dtype, map->mappings->set->key->dtype))
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
From ff6135270616ccf4712990246cae850e64253516 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||||
|
Date: Thu, 29 Feb 2024 16:50:37 +0100
|
||||||
|
Subject: [PATCH] rule: fix ASAN errors in chain priority to textual names
|
||||||
|
|
||||||
|
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 --git a/src/rule.c b/src/rule.c
|
||||||
|
index 342c43fb..adab584e 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;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
177
backport-src-do-not-allow-to-chain-more-than-16-binops.patch
Normal file
177
backport-src-do-not-allow-to-chain-more-than-16-binops.patch
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
From dcb199544563ded462cb7151134278f82a9e6cfd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Thu, 21 Dec 2023 11:25:14 +0100
|
||||||
|
Subject: [PATCH] src: do not allow to chain more than 16 binops
|
||||||
|
|
||||||
|
netlink_linearize.c has never supported more than 16 chained binops.
|
||||||
|
Adding more is possible but overwrites the stack in
|
||||||
|
netlink_gen_bitwise().
|
||||||
|
|
||||||
|
Add a recursion counter to catch this at eval stage.
|
||||||
|
|
||||||
|
Its not enough to just abort once the counter hits
|
||||||
|
NFT_MAX_EXPR_RECURSION.
|
||||||
|
|
||||||
|
This is because there are valid test cases that exceed this.
|
||||||
|
For example, evaluation of 1 | 2 will merge the constans, so even
|
||||||
|
if there are a dozen recursive eval calls this will not end up
|
||||||
|
with large binop chain post-evaluation.
|
||||||
|
|
||||||
|
v2: allow more than 16 binops iff the evaluation function
|
||||||
|
did constant-merging.
|
||||||
|
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
include/expression.h | 1 +
|
||||||
|
include/rule.h | 6 ++-
|
||||||
|
src/evaluate.c | 39 ++++++++++++++++++-
|
||||||
|
src/netlink_linearize.c | 7 +++-
|
||||||
|
.../bogons/nft-f/huge_binop_expr_chain_crash | 5 +++
|
||||||
|
5 files changed, 53 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/huge_binop_expr_chain_crash
|
||||||
|
|
||||||
|
diff --git a/include/expression.h b/include/expression.h
|
||||||
|
index 809089c8..f5d7e160 100644
|
||||||
|
--- a/include/expression.h
|
||||||
|
+++ b/include/expression.h
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
|
||||||
|
#define NFT_MAX_EXPR_LEN_BYTES (NFT_REG32_COUNT * sizeof(uint32_t))
|
||||||
|
#define NFT_MAX_EXPR_LEN_BITS (NFT_MAX_EXPR_LEN_BYTES * BITS_PER_BYTE)
|
||||||
|
+#define NFT_MAX_EXPR_RECURSION 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum expr_types
|
||||||
|
diff --git a/include/rule.h b/include/rule.h
|
||||||
|
index 6236d292..6835fe06 100644
|
||||||
|
--- a/include/rule.h
|
||||||
|
+++ b/include/rule.h
|
||||||
|
@@ -753,10 +753,13 @@ extern void cmd_free(struct cmd *cmd);
|
||||||
|
* @rule: current rule
|
||||||
|
* @set: current set
|
||||||
|
* @stmt: current statement
|
||||||
|
+ * @stmt_len: current statement template length
|
||||||
|
+ * @recursion: expr evaluation recursion counter
|
||||||
|
* @cache: cache context
|
||||||
|
* @debug_mask: debugging bitmask
|
||||||
|
* @ectx: expression context
|
||||||
|
- * @pctx: payload context
|
||||||
|
+ * @_pctx: payload contexts
|
||||||
|
+ * @inner_desc: inner header description
|
||||||
|
*/
|
||||||
|
struct eval_ctx {
|
||||||
|
struct nft_ctx *nft;
|
||||||
|
@@ -767,6 +770,7 @@ struct eval_ctx {
|
||||||
|
struct set *set;
|
||||||
|
struct stmt *stmt;
|
||||||
|
uint32_t stmt_len;
|
||||||
|
+ uint32_t recursion;
|
||||||
|
struct expr_ctx ectx;
|
||||||
|
struct proto_ctx _pctx[2];
|
||||||
|
const struct proto_desc *inner_desc;
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 26f0110f..41524eef 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -1418,6 +1418,13 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
|
||||||
|
struct expr *op = *expr, *left, *right;
|
||||||
|
const char *sym = expr_op_symbols[op->op];
|
||||||
|
unsigned int max_shift_len = ctx->ectx.len;
|
||||||
|
+ int ret = -1;
|
||||||
|
+
|
||||||
|
+ if (ctx->recursion >= USHRT_MAX)
|
||||||
|
+ return expr_binary_error(ctx->msgs, op, NULL,
|
||||||
|
+ "Binary operation limit %u reached ",
|
||||||
|
+ ctx->recursion);
|
||||||
|
+ ctx->recursion++;
|
||||||
|
|
||||||
|
if (expr_evaluate(ctx, &op->left) < 0)
|
||||||
|
return -1;
|
||||||
|
@@ -1472,14 +1479,42 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
|
||||||
|
switch (op->op) {
|
||||||
|
case OP_LSHIFT:
|
||||||
|
case OP_RSHIFT:
|
||||||
|
- return expr_evaluate_shift(ctx, expr);
|
||||||
|
+ ret = expr_evaluate_shift(ctx, expr);
|
||||||
|
+ break;
|
||||||
|
case OP_AND:
|
||||||
|
case OP_XOR:
|
||||||
|
case OP_OR:
|
||||||
|
- return expr_evaluate_bitwise(ctx, expr);
|
||||||
|
+ ret = expr_evaluate_bitwise(ctx, expr);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
BUG("invalid binary operation %u\n", op->op);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ if (ctx->recursion == 0)
|
||||||
|
+ BUG("recursion counter underflow");
|
||||||
|
+
|
||||||
|
+ /* can't check earlier: evaluate functions might do constant-merging + expr_free.
|
||||||
|
+ *
|
||||||
|
+ * So once we've evaluate everything check for remaining length of the
|
||||||
|
+ * binop chain.
|
||||||
|
+ */
|
||||||
|
+ if (--ctx->recursion == 0) {
|
||||||
|
+ unsigned int to_linearize = 0;
|
||||||
|
+
|
||||||
|
+ op = *expr;
|
||||||
|
+ while (op && op->etype == EXPR_BINOP && op->left != NULL) {
|
||||||
|
+ to_linearize++;
|
||||||
|
+ op = op->left;
|
||||||
|
+
|
||||||
|
+ if (to_linearize >= NFT_MAX_EXPR_RECURSION)
|
||||||
|
+ return expr_binary_error(ctx->msgs, op, NULL,
|
||||||
|
+ "Binary operation limit %u reached ",
|
||||||
|
+ NFT_MAX_EXPR_RECURSION);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int list_member_evaluate(struct eval_ctx *ctx, struct expr **expr)
|
||||||
|
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
|
||||||
|
index d8b41a08..50dbd36c 100644
|
||||||
|
--- a/src/netlink_linearize.c
|
||||||
|
+++ b/src/netlink_linearize.c
|
||||||
|
@@ -695,10 +695,10 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx,
|
||||||
|
const struct expr *expr,
|
||||||
|
enum nft_registers dreg)
|
||||||
|
{
|
||||||
|
+ struct expr *binops[NFT_MAX_EXPR_RECURSION];
|
||||||
|
struct nftnl_expr *nle;
|
||||||
|
struct nft_data_linearize nld;
|
||||||
|
struct expr *left, *i;
|
||||||
|
- struct expr *binops[16];
|
||||||
|
mpz_t mask, xor, val, tmp;
|
||||||
|
unsigned int len;
|
||||||
|
int n = 0;
|
||||||
|
@@ -710,8 +710,11 @@ static void netlink_gen_bitwise(struct netlink_linearize_ctx *ctx,
|
||||||
|
|
||||||
|
binops[n++] = left = (struct expr *) expr;
|
||||||
|
while (left->etype == EXPR_BINOP && left->left != NULL &&
|
||||||
|
- (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR))
|
||||||
|
+ (left->op == OP_AND || left->op == OP_OR || left->op == OP_XOR)) {
|
||||||
|
+ if (n == array_size(binops))
|
||||||
|
+ BUG("NFT_MAX_EXPR_RECURSION limit reached");
|
||||||
|
binops[n++] = left = left->left;
|
||||||
|
+ }
|
||||||
|
n--;
|
||||||
|
|
||||||
|
netlink_gen_expr(ctx, binops[n--], dreg);
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/huge_binop_expr_chain_crash b/tests/shell/testcases/bogons/nft-f/huge_binop_expr_chain_crash
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..8d1da726
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/huge_binop_expr_chain_crash
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+table t {
|
||||||
|
+ chain c {
|
||||||
|
+ meta oifname^a^b^c^d^e^f^g^h^i^j^k^l^m^n^o^p^q^r^s^t^u^v^w^x^y^z^A^B^C^D^E^F^G^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^0^1^2^3^4^5^6^7^8^9 bar
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
From ef10d65db278d77208e960d210a1f4f532ebb552 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Tue, 12 Dec 2023 19:13:14 +0100
|
||||||
|
Subject: [PATCH] src: reject large raw payload and concat expressions
|
||||||
|
|
||||||
|
The kernel will reject this too, but unfortunately nft may try
|
||||||
|
to cram the data into the underlying libnftnl expr.
|
||||||
|
|
||||||
|
This causes heap corruption or
|
||||||
|
BUG: nld buffer overflow: want to copy 132, max 64
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
Error: Concatenation of size 544 exceeds maximum size of 512
|
||||||
|
udp length . @th,0,512 . @th,512,512 { 47-63 . 0xe373135363130 . 0x33131303735353203 }
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
resp. same warning for an over-sized raw expression.
|
||||||
|
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
include/expression.h | 3 +++
|
||||||
|
src/evaluate.c | 8 ++++++++
|
||||||
|
src/parser_bison.y | 7 +++++++
|
||||||
|
.../bogons/nft-f/stack_overflow_via_large_concat_expr | 5 +++++
|
||||||
|
.../bogons/nft-f/stack_overflow_via_large_raw_expr | 5 +++++
|
||||||
|
5 files changed, 28 insertions(+)
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_concat_expr
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_raw_expr
|
||||||
|
|
||||||
|
diff --git a/include/expression.h b/include/expression.h
|
||||||
|
index aede223d..809089c8 100644
|
||||||
|
--- a/include/expression.h
|
||||||
|
+++ b/include/expression.h
|
||||||
|
@@ -11,6 +11,9 @@
|
||||||
|
#include <json.h>
|
||||||
|
#include <libnftnl/udata.h>
|
||||||
|
|
||||||
|
+#define NFT_MAX_EXPR_LEN_BYTES (NFT_REG32_COUNT * sizeof(uint32_t))
|
||||||
|
+#define NFT_MAX_EXPR_LEN_BITS (NFT_MAX_EXPR_LEN_BYTES * BITS_PER_BYTE)
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* enum expr_types
|
||||||
|
*
|
||||||
|
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||||
|
index 1c5078d6..87cd68d3 100644
|
||||||
|
--- a/src/evaluate.c
|
||||||
|
+++ b/src/evaluate.c
|
||||||
|
@@ -1591,6 +1591,10 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->inner_desc = NULL;
|
||||||
|
+
|
||||||
|
+ if (size > NFT_MAX_EXPR_LEN_BITS)
|
||||||
|
+ return expr_error(ctx->msgs, i, "Concatenation of size %u exceeds maximum size of %u",
|
||||||
|
+ size, NFT_MAX_EXPR_LEN_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*expr)->flags |= flags;
|
||||||
|
@@ -4719,6 +4723,10 @@ static int set_expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
|
||||||
|
dsize_bytes = div_round_up(i->len, BITS_PER_BYTE);
|
||||||
|
(*expr)->field_len[(*expr)->field_count++] = dsize_bytes;
|
||||||
|
size += netlink_padded_len(i->len);
|
||||||
|
+
|
||||||
|
+ if (size > NFT_MAX_EXPR_LEN_BITS)
|
||||||
|
+ return expr_error(ctx->msgs, i, "Concatenation of size %u exceeds maximum size of %u",
|
||||||
|
+ size, NFT_MAX_EXPR_LEN_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*expr)->flags |= flags;
|
||||||
|
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
||||||
|
index 571eddf1..7082d2ba 100644
|
||||||
|
--- a/src/parser_bison.y
|
||||||
|
+++ b/src/parser_bison.y
|
||||||
|
@@ -5627,6 +5627,13 @@ payload_expr : payload_raw_expr
|
||||||
|
|
||||||
|
payload_raw_expr : AT payload_base_spec COMMA NUM COMMA NUM close_scope_at
|
||||||
|
{
|
||||||
|
+ if ($6 > NFT_MAX_EXPR_LEN_BITS) {
|
||||||
|
+ erec_queue(error(&@1, "raw payload length %u exceeds upper limit of %u",
|
||||||
|
+ $6, NFT_MAX_EXPR_LEN_BITS),
|
||||||
|
+ state->msgs);
|
||||||
|
+ YYERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
$$ = payload_expr_alloc(&@$, NULL, 0);
|
||||||
|
payload_init_raw($$, $2, $4, $6);
|
||||||
|
$$->byteorder = BYTEORDER_BIG_ENDIAN;
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_concat_expr b/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_concat_expr
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..8b0d2744
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_concat_expr
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+table t {
|
||||||
|
+ chain c {
|
||||||
|
+ udp length . @th,0,512 . @th,512,512 { 47-63 . 0xe373135363130 . 0x33131303735353203 }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_raw_expr b/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_raw_expr
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..66bd6bf8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/stack_overflow_via_large_raw_expr
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+table t {
|
||||||
|
+ chain c {
|
||||||
|
+ @th,160,1272 gt 0
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
From c9f934ca446de5041ce6f19e4ee6a0c74b120186 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Fri, 15 Dec 2023 13:04:22 +0100
|
||||||
|
Subject: [PATCH] tcpopt: don't create exthdr expression without datatype
|
||||||
|
|
||||||
|
The reproducer crashes during concat evaluation, as the
|
||||||
|
exthdr expression lacks a datatype.
|
||||||
|
|
||||||
|
This should never happen, i->dtype must be set.
|
||||||
|
|
||||||
|
In this case the culprit is tcp option parsing, it will
|
||||||
|
wire up a non-existent template, because the "nop" option
|
||||||
|
has no length field (1 byte only).
|
||||||
|
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
src/tcpopt.c | 2 +-
|
||||||
|
tests/shell/testcases/bogons/nft-f/tcp_option_without_template | 1 +
|
||||||
|
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 tests/shell/testcases/bogons/nft-f/tcp_option_without_template
|
||||||
|
|
||||||
|
diff --git a/src/tcpopt.c b/src/tcpopt.c
|
||||||
|
index 8111a507..f977e417 100644
|
||||||
|
--- a/src/tcpopt.c
|
||||||
|
+++ b/src/tcpopt.c
|
||||||
|
@@ -224,7 +224,7 @@ struct expr *tcpopt_expr_alloc(const struct location *loc,
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl = &desc->templates[field];
|
||||||
|
- if (!tmpl)
|
||||||
|
+ if (!tmpl || !tmpl->dtype)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
expr = expr_alloc(loc, EXPR_EXTHDR, tmpl->dtype,
|
||||||
|
diff --git a/tests/shell/testcases/bogons/nft-f/tcp_option_without_template b/tests/shell/testcases/bogons/nft-f/tcp_option_without_template
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..fd732fd3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/bogons/nft-f/tcp_option_without_template
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+add rule f i tcp option nop length . @ih,32,3 1
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
From b237aeff41840f0c7968d02ed3d461fa9fa8fb70 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Westphal <fw@strlen.de>
|
||||||
|
Date: Fri, 8 Mar 2024 20:57:26 +0100
|
||||||
|
Subject: [PATCH] tests: shell: add regression test for double-free crash bug
|
||||||
|
|
||||||
|
BUG: KASAN: slab-use-after-free in nf_tables_set_elem_destroy+0x55/0x160
|
||||||
|
Call Trace:
|
||||||
|
nf_tables_set_elem_destroy+0x55/0x160
|
||||||
|
nf_tables_set_elem_destroy+0x55/0x160
|
||||||
|
nft_pipapo_destroy+0x3b4/0x5a0
|
||||||
|
nft_set_destroy+0x118/0x3a0
|
||||||
|
nf_tables_trans_destroy_work+0x4f2/0xa80
|
||||||
|
|
||||||
|
This is a test case for the bug fiex with kernel commit
|
||||||
|
b0e256f3dd2b ("netfilter: nft_set_pipapo: release elements in clone only from destroy path").
|
||||||
|
|
||||||
|
Reported-by: lonial con <kongln9170@gmail.com>
|
||||||
|
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||||
|
---
|
||||||
|
.../testcases/transactions/concat_range_abort | 28 +++++++++++
|
||||||
|
.../dumps/concat_range_abort.json-nft | 47 +++++++++++++++++++
|
||||||
|
.../transactions/dumps/concat_range_abort.nft | 8 ++++
|
||||||
|
3 files changed, 83 insertions(+)
|
||||||
|
create mode 100755 tests/shell/testcases/transactions/concat_range_abort
|
||||||
|
create mode 100644 tests/shell/testcases/transactions/dumps/concat_range_abort.json-nft
|
||||||
|
create mode 100644 tests/shell/testcases/transactions/dumps/concat_range_abort.nft
|
||||||
|
|
||||||
|
diff --git a/tests/shell/testcases/transactions/concat_range_abort b/tests/shell/testcases/transactions/concat_range_abort
|
||||||
|
new file mode 100755
|
||||||
|
index 00000000..b2bbe37b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/transactions/concat_range_abort
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+
|
||||||
|
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_pipapo)
|
||||||
|
+
|
||||||
|
+set -e
|
||||||
|
+
|
||||||
|
+$NFT -f /dev/stdin <<EOF
|
||||||
|
+table ip x {
|
||||||
|
+ map m {
|
||||||
|
+ typeof ip saddr . meta mark : verdict
|
||||||
|
+ flags interval
|
||||||
|
+ counter
|
||||||
|
+ elements = {
|
||||||
|
+ 127.0.0.1-127.0.0.4 . 0x123434-0xb00122 : jump foo,
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ chain foo {
|
||||||
|
+ accept
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+EOF
|
||||||
|
+
|
||||||
|
+$NFT -f /dev/stdin <<EOF
|
||||||
|
+add chain ip x bar
|
||||||
|
+add element ip x m { 1.2.3.4 . 42 : jump bar }
|
||||||
|
+delete set ip x m
|
||||||
|
+EOF
|
||||||
|
diff --git a/tests/shell/testcases/transactions/dumps/concat_range_abort.json-nft b/tests/shell/testcases/transactions/dumps/concat_range_abort.json-nft
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..8db71894
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/transactions/dumps/concat_range_abort.json-nft
|
||||||
|
@@ -0,0 +1,47 @@
|
||||||
|
+{
|
||||||
|
+ "nftables": [
|
||||||
|
+ {
|
||||||
|
+ "metainfo": {
|
||||||
|
+ "version": "VERSION",
|
||||||
|
+ "release_name": "RELEASE_NAME",
|
||||||
|
+ "json_schema_version": 1
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "table": {
|
||||||
|
+ "family": "ip",
|
||||||
|
+ "name": "x",
|
||||||
|
+ "handle": 0
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "chain": {
|
||||||
|
+ "family": "ip",
|
||||||
|
+ "table": "x",
|
||||||
|
+ "name": "foo",
|
||||||
|
+ "handle": 0
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "chain": {
|
||||||
|
+ "family": "ip",
|
||||||
|
+ "table": "x",
|
||||||
|
+ "name": "bar",
|
||||||
|
+ "handle": 0
|
||||||
|
+ }
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ "rule": {
|
||||||
|
+ "family": "ip",
|
||||||
|
+ "table": "x",
|
||||||
|
+ "chain": "foo",
|
||||||
|
+ "handle": 0,
|
||||||
|
+ "expr": [
|
||||||
|
+ {
|
||||||
|
+ "accept": null
|
||||||
|
+ }
|
||||||
|
+ ]
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ ]
|
||||||
|
+}
|
||||||
|
diff --git a/tests/shell/testcases/transactions/dumps/concat_range_abort.nft b/tests/shell/testcases/transactions/dumps/concat_range_abort.nft
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..06adca7a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/shell/testcases/transactions/dumps/concat_range_abort.nft
|
||||||
|
@@ -0,0 +1,8 @@
|
||||||
|
+table ip x {
|
||||||
|
+ chain foo {
|
||||||
|
+ accept
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ chain bar {
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
Name: nftables
|
Name: nftables
|
||||||
Version: 1.0.8
|
Version: 1.0.8
|
||||||
Release: 4
|
Release: 5
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Summary: A subsystem of the Linux kernel processing network data
|
Summary: A subsystem of the Linux kernel processing network data
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
@ -55,6 +55,16 @@ Patch0043: backport-evaluate-release-mpz-type-in-expr_evaluate_list-erro.pa
|
|||||||
Patch0044: backport-expression-missing-line-in-describe-command-with-inv.patch
|
Patch0044: backport-expression-missing-line-in-describe-command-with-inv.patch
|
||||||
Patch0045: backport-evaluate-handle-invalid-mapping-expressions-graceful.patch
|
Patch0045: backport-evaluate-handle-invalid-mapping-expressions-graceful.patch
|
||||||
|
|
||||||
|
Patch0046: backport-evaluate-disable-meta-set-with-ranges.patch
|
||||||
|
Patch0047: backport-src-reject-large-raw-payload-and-concat-expressions.patch
|
||||||
|
Patch0048: backport-evaluate-fix-stack-overflow-with-huge-priority-string.patch
|
||||||
|
Patch0049: backport-tcpopt-don-t-create-exthdr-expression-without-datatype.patch
|
||||||
|
Patch0050: backport-src-do-not-allow-to-chain-more-than-16-binops.patch
|
||||||
|
Patch0051: backport-rule-fix-ASAN-errors-in-chain-priority-to-textual-names.patch
|
||||||
|
Patch0052: backport-tests-shell-add-regression-test-for-double-free-crash-bug.patch
|
||||||
|
Patch0053: backport-evaluate-handle-invalid-mapping-expressions-in-stateful-object-statements-gracefully.patch
|
||||||
|
Patch0054: backport-evaluate-Fix-incorrect-checking-the-base-variable-in-case-of-IPV6.patch
|
||||||
|
|
||||||
BuildRequires: gcc flex bison libmnl-devel gmp-devel readline-devel libnftnl-devel docbook2X systemd
|
BuildRequires: gcc flex bison libmnl-devel gmp-devel readline-devel libnftnl-devel docbook2X systemd
|
||||||
BuildRequires: iptables-devel jansson-devel python3-devel
|
BuildRequires: iptables-devel jansson-devel python3-devel
|
||||||
BuildRequires: chrpath libedit-devel
|
BuildRequires: chrpath libedit-devel
|
||||||
@ -153,6 +163,21 @@ echo "%{_libdir}" > %{buildroot}/etc/ld.so.conf.d/%{name}-%{_arch}.conf
|
|||||||
%{python3_sitelib}/nftables/
|
%{python3_sitelib}/nftables/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Sep 25 2024 gaihuiying <eaglegai@163.com> - 1:1.0.8-5
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:backport upstream patches
|
||||||
|
evaluate: disable meta set with ranges
|
||||||
|
src: reject large raw payload and concat expressions
|
||||||
|
evaluate: fix stack overflow with huge priority string
|
||||||
|
tcpopt: don't create exthdr expression without datatype
|
||||||
|
src: do not allow to chain more than 16 binops
|
||||||
|
rule: fix ASAN errors in chain priority to textual names
|
||||||
|
tests: shell: add regression test for double-free crash bug
|
||||||
|
evaluate: handle invalid mapping expressions in stateful object
|
||||||
|
evaluate: Fix incorrect checking the `base` variable in case of IPV6
|
||||||
|
|
||||||
* Mon Jun 24 2024 liweigang <liweiganga@uniontech.com> - 1:1.0.8-4
|
* Mon Jun 24 2024 liweigang <liweiganga@uniontech.com> - 1:1.0.8-4
|
||||||
- Type: bugfix
|
- Type: bugfix
|
||||||
- CVE: NA
|
- CVE: NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user