114 lines
3.9 KiB
Diff
114 lines
3.9 KiB
Diff
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
|
|
|