Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
c9bd2790f6
!110 Optimize the cache to fix firewalld
From: @yangl777 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2025-01-27 06:42:46 +00:00
yangl777
2ba837a96b Optimize the cache to fix firewalld 2025-01-27 06:06:13 +00:00
openeuler-ci-bot
1c15b0cd98
!102 backport upstream patches
From: @eaglegai 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2024-12-12 01:37:17 +00:00
eaglegai
4d97c1a79d backport upstream patches 2024-12-11 03:11:06 +00:00
openeuler-ci-bot
514634f8b5
!94 fix coredumps
From: @eaglegai 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2024-12-10 06:32:36 +00:00
eaglegai
7f62a054c8 fix coredumps 2024-12-10 03:14:16 +00:00
openeuler-ci-bot
092778a34d
!86 backport upstream patches
From: @eaglegai 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2024-09-25 07:27:59 +00:00
eaglegai
a750fa148f backport upstream patches 2024-09-25 06:40:55 +00:00
openeuler-ci-bot
27c1f3c333
!81 backport upstream patches
From: @eaglegai 
Reviewed-by: @sunsuwan 
Signed-off-by: @sunsuwan
2024-06-26 08:16:01 +00:00
eaglegai
07634d79d5 backport upstream patches 2024-06-26 03:51:24 +00:00
29 changed files with 2207 additions and 5 deletions

View File

@ -0,0 +1,84 @@
From e3d00ed1f657d5ce989a780990c6fb0097368d1e Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 12 Jan 2022 01:34:00 +0100
Subject: cache: add helper function to fill up the rule cache
Add a helper function to dump the rules and add them to the
corresponding chain.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:change about netlink_list_rules and rule_cache_init
Reference:https://git.netfilter.org/nftables/commit/?id=e3d00ed1f657d5ce989a780990c6fb0097368d1e
---
src/cache.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 15 deletions(-)
diff --git a/src/cache.c b/src/cache.c
index 0e9e7fe5..14957f2d 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -811,6 +811,28 @@ static int cache_init_tables(struct netlink_ctx *ctx, struct handle *h,
return 0;
}
+static int rule_init_cache(struct netlink_ctx *ctx, struct table *table)
+{
+ struct rule *rule, *nrule;
+ struct chain *chain;
+ int ret;
+
+ ret = netlink_list_rules(ctx, &table->handle);
+
+ list_for_each_entry_safe(rule, nrule, &ctx->list, list) {
+ chain = chain_cache_find(table, rule->handle.chain.name);
+ if (!chain)
+ chain = chain_binding_lookup(table,
+ rule->handle.chain.name);
+ if (!chain)
+ return -1;
+
+ list_move_tail(&rule->list, &chain->rules);
+ }
+
+ return ret;
+}
+
static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags)
{
struct nftnl_flowtable_list *ft_list = NULL;
@@ -818,9 +841,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
struct nftnl_chain_list *chain_list = NULL;
struct nftnl_set_list *set_list = NULL;
struct nftnl_obj_list *obj_list;
- struct rule *rule, *nrule;
struct table *table;
- struct chain *chain;
struct set *set;
int ret = 0;
@@ -902,19 +923,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags,
}
if (flags & NFT_CACHE_RULE_BIT) {
- ret = netlink_list_rules(ctx, &table->handle);
- list_for_each_entry_safe(rule, nrule, &ctx->list, list) {
- chain = chain_cache_find(table, rule->handle.chain.name);
- if (!chain)
- chain = chain_binding_lookup(table,
- rule->handle.chain.name);
- if (!chain) {
- ret = -1;
- goto cache_fails;
- }
-
- list_move_tail(&rule->list, &chain->rules);
- }
+ ret = rule_init_cache(ctx, table);
if (ret < 0) {
ret = -1;
goto cache_fails;
--
cgit v1.2.3

View File

@ -0,0 +1,75 @@
From 64c74ba5795bbdd8c8080380bc1e66dec55cde65 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 18 Jul 2022 15:56:00 +0200
Subject: cache: prepare nft_cache_evaluate() to return error
Move flags as parameter reference and add list of error messages to prepare
for sanity checks.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:remove change about filter,we don't have
Reference:https://git.netfilter.org/nftables/commit/?id=64c74ba5795bbdd8c8080380bc1e66dec55cde65
---
include/cache.h | 5 +++--
src/cache.c | 8 +++++---
src/libnftables.c | 5 ++++-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/include/cache.h b/include/cache.h
index b6c7d48b..575381ef 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -65,7 +65,8 @@ struct nft_cache_filter {
struct nft_cache;
enum cmd_ops;
-unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds);
+int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
+ struct list_head *msgs, unsigned int *flags);
int nft_cache_update(struct nft_ctx *ctx, enum cmd_ops cmd,
struct list_head *msgs);
bool nft_cache_needs_update(struct nft_cache *cache);
diff --git a/src/cache.c b/src/cache.c
index b6ae2310..9e2fe950 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -262,7 +262,8 @@ static unsigned int evaluate_cache_list(struct nft_ctx *nft, struct cmd *cmd,
return flags;
}
-unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
+int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
+ struct list_head *msgs, unsigned int *pflags)
{
unsigned int flags = NFT_CACHE_EMPTY;
struct cmd *cmd;
@@ -318,8 +319,9 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
break;
}
}
+ *pflags = flags;
- return flags;
+ return 0;
}
void table_cache_add(struct table *table, struct nft_cache *cache)
diff --git a/src/libnftables.c b/src/libnftables.c
index f2a1ef04..a376825d 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -506,7 +506,9 @@ static int nft_evaluate(struct nft_ctx *nft, struct list_head *msgs,
unsigned int flags;
struct cmd *cmd;
- flags = nft_cache_evaluate(nft, cmds);
+ if (nft_cache_evaluate(nft, cmds, msgs, &flags) < 0) {
+ return -1;
+ }
if (nft_cache_update(nft, flags, msgs) < 0)
return -1;
--
cgit v1.2.3

View File

@ -0,0 +1,49 @@
From 8a6cdfaff058412b3d0efec45541cd7d610aeefa Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 6 Jul 2022 13:21:34 +0200
Subject: cache: release pending rules when chain binding lookup fails
If the implicit chain is not in the cache, release pending rules in
ctx->list and report EINTR to let the cache core retry to populate a
consistent cache.
Fixes: c330152b7f77 ("src: support for implicit chain bindings")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:change context
Reference:https://git.netfilter.org/nftables/commit/?id=8a6cdfaff058412b3d0efec45541cd7d610aeefa
---
src/cache.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/cache.c b/src/cache.c
index fd8df884..b6ae2310 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -847,12 +847,21 @@ static int rule_init_cache(struct netlink_ctx *ctx, struct table *table,
chain = chain_binding_lookup(table,
rule->handle.chain.name);
if (!chain)
- return -1;
+ goto err_ctx_list;
list_move_tail(&rule->list, &chain->rules);
}
return ret;
+
+err_ctx_list:
+ list_for_each_entry_safe(rule, nrule, &ctx->list, list) {
+ list_del(&rule->list);
+ rule_free(rule);
+ }
+ errno = EINTR;
+
+ return -1;
}
static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags)
--
cgit v1.2.3

View File

@ -139,11 +139,8 @@ index c1f0972..828e4cc 100644
static unsigned int evaluate_cache_del(struct cmd *cmd, unsigned int flags)
{
switch (cmd->obj) {
@@ -121,8 +225,12 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
{
unsigned int flags = NFT_CACHE_EMPTY;
@@ -121,6 +225,9 @@ unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
struct cmd *cmd;
+ struct list_head *msgs;
list_for_each_entry(cmd, cmds, list) {
+ if (nft_handle_validate(cmd, msgs) < 0)

View File

@ -0,0 +1,88 @@
From a8ff324dc64fd76f7d218d3d94c5885250951258 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Fri, 28 Jul 2023 21:04:13 +0200
Subject: ct expectation: fix 'list object x' vs. 'list objects in table'
confusion
Just like "ct timeout", "ct expectation" is in need of the same fix,
we get segfault on "nft list ct expectation table t", if table t exists.
This is the exact same pattern as resolved for "ct timeout" in commit
1d2e22fc0521 ("ct timeout: fix 'list object x' vs. 'list objects in table' confusion").
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict:change context in parser_bison.y
Reference:https://git.netfilter.org/nftables/commit/?id=a8ff324dc64fd76f7d218d3d94c5885250951258
---
include/rule.h | 1 +
src/cache.c | 1 +
src/evaluate.c | 1 +
src/parser_bison.y | 2 +-
src/rule.c | 1 +
5 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/rule.h b/include/rule.h
index 5cb549c2..13ab1bf3 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -649,6 +649,7 @@ enum cmd_obj {
CMD_OBJ_SECMARK,
CMD_OBJ_SECMARKS,
CMD_OBJ_CT_EXPECT,
+ CMD_OBJ_CT_EXPECTATIONS,
CMD_OBJ_SYNPROXY,
CMD_OBJ_SYNPROXYS,
CMD_OBJ_HOOKS,
diff --git a/src/cache.c b/src/cache.c
index 5cab2622..b6a7e194 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -377,6 +377,7 @@ static int nft_handle_validate(const struct cmd *cmd, struct list_head *msgs)
case CMD_OBJ_CT_TIMEOUT:
case CMD_OBJ_CT_TIMEOUTS:
case CMD_OBJ_CT_EXPECT:
+ case CMD_OBJ_CT_EXPECTATIONS:
if (h->table.name &&
strlen(h->table.name) > NFT_NAME_MAXLEN) {
loc = &h->table.location;
diff --git a/src/evaluate.c b/src/evaluate.c
index 33e4ac93..8fc1ca7e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -5425,6 +5425,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_SECMARKS:
case CMD_OBJ_SYNPROXYS:
case CMD_OBJ_CT_TIMEOUTS:
+ case CMD_OBJ_CT_EXPECTATIONS:
if (cmd->handle.table.name == NULL)
return 0;
if (!table_cache_find(&ctx->nft->cache.table_cache,
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 553ddf97..ef5011c1 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4770,7 +4770,7 @@ ct_obj_type : HELPER { $$ = NFT_OBJECT_CT_HELPER; }
ct_cmd_type : HELPERS { $$ = CMD_OBJ_CT_HELPERS; }
| TIMEOUT { $$ = CMD_OBJ_CT_TIMEOUTS; }
- | EXPECTATION { $$ = CMD_OBJ_CT_EXPECT; }
+ | EXPECTATION { $$ = CMD_OBJ_CT_EXPECTATIONS; }
;
ct_l4protoname : TCP { $$ = IPPROTO_TCP; }
diff --git a/src/rule.c b/src/rule.c
index f4d00a8d..4e60c1e6 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2360,6 +2360,7 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_CT_TIMEOUTS:
return do_list_obj(ctx, cmd, NFT_OBJECT_CT_TIMEOUT);
case CMD_OBJ_CT_EXPECT:
+ case CMD_OBJ_CT_EXPECTATIONS:
return do_list_obj(ctx, cmd, NFT_OBJECT_CT_EXPECT);
case CMD_OBJ_LIMIT:
case CMD_OBJ_LIMITS:
--
cgit v1.2.3

View File

@ -0,0 +1,106 @@
From 1d2e22fc0521bcf73ee1f891c291dc1bde47a6bb Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Mon, 19 Jun 2023 22:43:06 +0200
Subject: ct timeout: fix 'list object x' vs. 'list objects in table' confusion
<empty ruleset>
$ nft list ct timeout table t
Error: No such file or directory
list ct timeout table t
^
This is expected to list all 'ct timeout' objects.
The failure is correct, the table 't' does not exist.
But now lets add one:
$ nft add table t
$ nft list ct timeout table t
Segmentation fault (core dumped)
... and thats not expected, nothing should be shown
and nft should exit normally.
Because of missing TIMEOUTS command enum, the backend thinks
it should do an object lookup, but as frontend asked for
'list of objects' rather than 'show this object',
handle.obj.name is NULL, which then results in this crash.
Update the command enums so that backend knows what the
frontend asked for.
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict:NA
Reference:https://git.netfilter.org/nftables/commit/?id=1d2e22fc0521bcf73ee1f891c291dc1bde47a6bb
---
include/rule.h | 1 +
src/cache.c | 1 +
src/evaluate.c | 1 +
src/parser_bison.y | 2 +-
src/rule.c | 1 +
5 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/rule.h b/include/rule.h
index fa391529..b360e261 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -645,6 +645,7 @@ enum cmd_obj {
CMD_OBJ_FLOWTABLE,
CMD_OBJ_FLOWTABLES,
CMD_OBJ_CT_TIMEOUT,
+ CMD_OBJ_CT_TIMEOUTS,
CMD_OBJ_SECMARK,
CMD_OBJ_SECMARKS,
CMD_OBJ_CT_EXPECT,
diff --git a/src/cache.c b/src/cache.c
index becfa57f..d908ae0a 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -370,6 +370,7 @@ static int nft_handle_validate(const struct cmd *cmd, struct list_head *msgs)
case CMD_OBJ_CT_HELPER:
case CMD_OBJ_CT_HELPERS:
case CMD_OBJ_CT_TIMEOUT:
+ case CMD_OBJ_CT_TIMEOUTS:
case CMD_OBJ_CT_EXPECT:
if (h->table.name &&
strlen(h->table.name) > NFT_NAME_MAXLEN) {
diff --git a/src/evaluate.c b/src/evaluate.c
index efab2895..687f9a7b 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -5441,6 +5441,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_FLOWTABLES:
case CMD_OBJ_SECMARKS:
case CMD_OBJ_SYNPROXYS:
+ case CMD_OBJ_CT_TIMEOUTS:
if (cmd->handle.table.name == NULL)
return 0;
if (!table_cache_find(&ctx->nft->cache.table_cache,
diff --git a/src/parser_bison.y b/src/parser_bison.y
index e7ee56c1..beb277b6 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4757,7 +4757,7 @@ ct_obj_type : HELPER { $$ = NFT_OBJECT_CT_HELPER; }
;
ct_cmd_type : HELPERS { $$ = CMD_OBJ_CT_HELPERS; }
- | TIMEOUT { $$ = CMD_OBJ_CT_TIMEOUT; }
+ | TIMEOUT { $$ = CMD_OBJ_CT_TIMEOUTS; }
| EXPECTATION { $$ = CMD_OBJ_CT_EXPECT; }
;
diff --git a/src/rule.c b/src/rule.c
index 1faa1a27..3704600a 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2351,6 +2351,7 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_CT_HELPERS:
return do_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER);
case CMD_OBJ_CT_TIMEOUT:
+ case CMD_OBJ_CT_TIMEOUTS:
return do_list_obj(ctx, cmd, NFT_OBJECT_CT_TIMEOUT);
case CMD_OBJ_CT_EXPECT:
return do_list_obj(ctx, cmd, NFT_OBJECT_CT_EXPECT);
--
cgit v1.2.3

View File

@ -0,0 +1,32 @@
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: 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>
Conflict:change evaluate.c context
Reference:https://git.netfilter.org/nftables/commit/?id=f6b579344eee17e5587b6a7fcc444fe997cd8cb6
---
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 = ctx->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)
--
cgit v1.2.3

View File

@ -0,0 +1,76 @@
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: 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>
Conflict: change evaluate.c to set ret
Reference:https://git.netfilter.org/nftables/commit/?id=d99b44adc5cfc455fdafd9b4bdabd413edf9a38a
---
src/evaluate.c | 13 +++++++++++++
.../testcases/bogons/nft-f/unknown_expr_type_range_assert | 5 +++++
2 files changed, 25 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 ec8e05f..1d3b142 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2725,11 +2725,26 @@ static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_meta(struct eval_ctx *ctx, struct stmt *stmt)
{
- return stmt_evaluate_arg(ctx, stmt,
- stmt->meta.tmpl->dtype,
- stmt->meta.tmpl->len,
- stmt->meta.tmpl->byteorder,
- &stmt->meta.expr);
+ int ret;
+ ret = stmt_evaluate_arg(ctx, stmt,
+ stmt->meta.tmpl->dtype,
+ stmt->meta.tmpl->len,
+ stmt->meta.tmpl->byteorder,
+ &stmt->meta.expr);
+ 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;
}
static int stmt_evaluate_ct(struct eval_ctx *ctx, struct stmt *stmt)
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
+ }
+}
--
cgit v1.2.3

View File

@ -0,0 +1,52 @@
From 45a4d4434742b425d019623812f2cce293033cdf Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Mon, 4 Dec 2023 18:30:51 +0100
Subject: evaluate: error out if basetypes are different
prefer
binop_with_different_basetype_assert:3:29-35: Error: Binary operation (<<) with different base types (string vs integer) is not supported
oifname set ip9dscp << 26 | 0x10
^^^^^^^~~~~~~
to assertion failure.
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict: NA
Reference: https://git.netfilter.org/nftables/commit/?id=45a4d4434742b425d019623812f2cce293033cdf
---
src/evaluate.c | 7 +++++--
.../testcases/bogons/nft-f/binop_with_different_basetype_assert | 5 +++++
2 files changed, 10 insertions(+), 2 deletions(-)
create mode 100644 tests/shell/testcases/bogons/nft-f/binop_with_different_basetype_assert
diff --git a/src/evaluate.c b/src/evaluate.c
index b6670254..51ae276a 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1451,8 +1451,11 @@ static int expr_evaluate_binop(struct eval_ctx *ctx, struct expr **expr)
"for %s expressions",
sym, expr_name(right));
- /* The grammar guarantees this */
- assert(datatype_equal(expr_basetype(left), expr_basetype(right)));
+ if (!datatype_equal(expr_basetype(left), expr_basetype(right)))
+ return expr_binary_error(ctx->msgs, left, op,
+ "Binary operation (%s) with different base types "
+ "(%s vs %s) is not supported",
+ sym, expr_basetype(left)->name, expr_basetype(right)->name);
switch (op->op) {
case OP_LSHIFT:
diff --git a/tests/shell/testcases/bogons/nft-f/binop_with_different_basetype_assert b/tests/shell/testcases/bogons/nft-f/binop_with_different_basetype_assert
new file mode 100644
index 00000000..e8436008
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-f/binop_with_different_basetype_assert
@@ -0,0 +1,5 @@
+table ip t {
+ chain c {
+ oifname set ip9dscp << 26 | 0x10
+ }
+}
--
cgit v1.2.3

View File

@ -0,0 +1,46 @@
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>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=b626c86abaf294fcf1ec788f722071dc90da68c4
---
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

View File

@ -0,0 +1,39 @@
From 3671c48970031e617ee713b79caf8ef0a1b096c2 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Mon, 4 Dec 2023 18:18:07 +0100
Subject: evaluate: guard against NULL basetype
i->dtype->basetype can be NULL.
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=3671c48970031e617ee713b79caf8ef0a1b096c2
---
src/evaluate.c | 2 +-
tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
diff --git a/src/evaluate.c b/src/evaluate.c
index b6428018..b6670254 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1610,7 +1610,7 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr)
return expr_error(ctx->msgs, i,
"List member must be a constant "
"value");
- if (i->dtype->basetype->type != TYPE_BITMASK)
+ if (datatype_basetype(i->dtype)->type != TYPE_BITMASK)
return expr_error(ctx->msgs, i,
"Basetype of type %s is not bitmask",
i->dtype->desc);
diff --git a/tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash b/tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
new file mode 100644
index 00000000..16d3e41f
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
@@ -0,0 +1 @@
+cPoR et ip dscp << 2>0 ,xl rt ipsec c0tt in tabl rt ipsec cl
--
cgit v1.2.3

View File

@ -0,0 +1,47 @@
From 778e4e113673c2a4daa798634c554c40f2808276 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Mon, 4 Dec 2023 17:47:50 +0100
Subject: evaluate: handle invalid mapping expressions gracefully
Before:
BUG: invalid mapping expression binop
nft: src/evaluate.c:2027: expr_evaluate_map: Assertion `0' failed.
After:
tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert:1:22-25: Error: invalid mapping expression binop
xy mame ip saddr map h& p p
~~~~~~~~ ^^^^
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict: evaluate.c change the context
Reference:https://git.netfilter.org/nftables/commit/?id=778e4e113673c2a4daa798634c554c40f2808276
---
src/evaluate.c | 4 ++--
tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
create mode 100644 tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert
diff --git a/src/evaluate.c b/src/evaluate.c
index 64deb31a..b6428018 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2024,8 +2024,8 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
"Expression is not a map");
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))
diff --git a/tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert b/tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert
new file mode 100644
index 00000000..7205ff4f
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert
@@ -0,0 +1 @@
+xy mame ip saddr map h& p p
--
cgit v1.2.3

View File

@ -0,0 +1,45 @@
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: 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>
Conflict:change evaluate.c context
Reference:https://git.netfilter.org/nftables/commit/?id=52a7af9bec15a4fb4bfea86e40b70f96098f7dfd
---
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))
--
cgit v1.2.3

View File

@ -0,0 +1,56 @@
From 5f43ea807bb0f5b30f332c2c96f13e33c9243d22 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Mon, 4 Dec 2023 22:00:06 +0100
Subject: evaluate: reject attempt to update a set
This will crash as set->data is NULL, so check that SET_REF is pointing
to a map:
Error: candidates_ipv4 is not a map
tcp dport 10003 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 { ip saddr . 10 :0004 timeout 1s }
~~~~~~~~~~~~~~~~
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict: evaluate.c change the context
Reference: https://git.netfilter.org/nftables/commit/?id=5f43ea807bb0f5b30f332c2c96f13e33c9243d22
---
src/evaluate.c | 4 ++++
tests/shell/testcases/bogons/nft-f/add_to_a_set_crash | 11 +++++++++++
2 files changed, 15 insertions(+)
create mode 100644 tests/shell/testcases/bogons/nft-f/add_to_a_set_crash
diff --git a/src/evaluate.c b/src/evaluate.c
index 131b0a0e..f05cac41 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -4344,6 +4344,10 @@ static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt)
return expr_error(ctx->msgs, stmt->map.set,
"Expression does not refer to a set");
+ if (!set_is_map(stmt->map.set->set->flags))
+ return expr_error(ctx->msgs, stmt->map.set,
+ "%s is not a map", stmt->map.set->set->handle.set.name);
+
if (stmt_evaluate_arg(ctx, stmt,
stmt->map.set->set->key->dtype,
stmt->map.set->set->key->len,
diff --git a/tests/shell/testcases/bogons/nft-f/add_to_a_set_crash b/tests/shell/testcases/bogons/nft-f/add_to_a_set_crash
new file mode 100644
index 00000000..80a01b45
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-f/add_to_a_set_crash
@@ -0,0 +1,11 @@
+table t {
+ set candidates_ipv4 {
+ type ipv4_addr . inet_service
+ size 65535
+ flags dynamic,timeout
+ }
+
+ chain input {
+ tcp dport 10003 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 { ip saddr . 10 :0004 timeout 1s }
+ }
+}
--
cgit v1.2.3

View File

@ -0,0 +1,55 @@
From 172b660843501463a0894b0d2ca1dd48c898dc4d Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 11 Jan 2024 22:14:34 +0100
Subject: evaluate: release mpz type in expr_evaluate_list() error path
Detected when running:
# nft -f tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
==383222==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 8 byte(s) in 1 object(s) allocated from:
#0 0x7fe7b54a9e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7fe7b538b9a9 in __gmp_default_allocate (/lib/x86_64-linux-gnu/libgmp.so.10+0xc9a9)
Fixes: 3671c4897003 ("evaluate: guard against NULL basetype")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict: NA
Reference: https://git.netfilter.org/nftables/commit/?id=172b660843501463a0894b0d2ca1dd48c898dc4d
---
src/evaluate.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 6c29579f..3b366166 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1695,16 +1695,22 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr)
mpz_init_set_ui(val, 0);
list_for_each_entry_safe(i, next, &list->expressions, list) {
- if (list_member_evaluate(ctx, &i) < 0)
+ if (list_member_evaluate(ctx, &i) < 0) {
+ mpz_clear(val);
return -1;
- if (i->etype != EXPR_VALUE)
+ }
+ if (i->etype != EXPR_VALUE) {
+ mpz_clear(val);
return expr_error(ctx->msgs, i,
"List member must be a constant "
"value");
- if (datatype_basetype(i->dtype)->type != TYPE_BITMASK)
+ }
+ if (datatype_basetype(i->dtype)->type != TYPE_BITMASK) {
+ mpz_clear(val);
return expr_error(ctx->msgs, i,
"Basetype of type %s is not bitmask",
i->dtype->desc);
+ }
mpz_ior(val, val, i->value);
}
--
cgit v1.2.3

View File

@ -0,0 +1,43 @@
From 2b24dd29c5fa1c7e4cf44f0753752d25106273a0 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Tue, 13 Feb 2024 17:09:20 +0100
Subject: expression: missing line in describe command with invalid expression
Before:
duh@testbed:~# nft describe blah
symbol expression, datatype invalid (invalid)duh@testbed:#
After:
duh@testbed:~# nft describe blah
symbol expression, datatype invalid (invalid)
duh@testbed:#
Fixes: 48aca2de80a7 ("iptopt: fix crash with invalid field/type combo")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=2b24dd29c5fa1c7e4cf44f0753752d25106273a0
---
src/expression.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/expression.c b/src/expression.c
index dde48b6a..cb2573fe 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -140,8 +140,10 @@ void expr_describe(const struct expr *expr, struct output_ctx *octx)
} else {
nft_print(octx, "%s expression, datatype %s (%s)",
expr_name(expr), dtype->name, dtype->desc);
- if (dtype == &invalid_type)
+ if (dtype == &invalid_type) {
+ nft_print(octx, "\n");
return;
+ }
}
if (dtype->basetype != NULL) {
--
cgit v1.2.3

View File

@ -0,0 +1,34 @@
From d361be1f8734461e27117f6c569acf2189fcf81e Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Tue, 3 Sep 2024 17:43:19 +0200
Subject: libnftables: Zero ctx->vars after freeing it
Leaving the invalid pointer value in place will cause a double-free when
users call nft_ctx_clear_vars() first, then nft_ctx_free(). Moreover,
nft_ctx_add_var() passes the pointer to mrealloc() and thus assumes it
to be either NULL or valid.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1772
Fixes: 9edaa6a51eab4 ("src: add --define key=value")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Conflict:change context from free to xfree
Reference:https://git.netfilter.org/nftables/commit/?id=d361be1f8734461e27117f6c569acf2189fcf81e
---
src/libnftables.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libnftables.c b/src/libnftables.c
index 7fc81515..2ae21501 100644
--- a/src/libnftables.c
+++ b/src/libnftables.c
@@ -160,6 +160,7 @@ void nft_ctx_clear_vars(struct nft_ctx *ctx)
}
ctx->num_vars = 0;
xfree(ctx->vars);
+ ctx->vars = NULL;
}
EXPORT_SYMBOL(nft_ctx_add_include_path);
--
cgit v1.2.3

View File

@ -0,0 +1,77 @@
From 0693edb9eb01fa5a479dcca7d30b06f52806d22a Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 16 Sep 2021 13:51:23 +0200
Subject: [PATCH] netlink: reset temporary set element stmt list after list
splice
Reset temporary stmt list to deal with the key_end case which might
result in a jump backward to handle the rhs of the interval.
Reported-by: Martin Zatloukal <slezi2@pvfree.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=0693edb9eb01fa5a479dcca7d30b06f52806d22a
---
src/netlink.c | 2 +-
tests/shell/testcases/maps/0013map_0 | 14 ++++++++++++++
tests/shell/testcases/maps/dumps/0013map_0.nft | 13 +++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100755 tests/shell/testcases/maps/0013map_0
create mode 100644 tests/shell/testcases/maps/dumps/0013map_0.nft
diff --git a/src/netlink.c b/src/netlink.c
index 9a0d96f0..28a5514a 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1324,7 +1324,7 @@ key_end:
nftnl_set_elem_expr_foreach(nlse, set_elem_parse_expressions,
&setelem_parse_ctx);
}
- list_splice_tail(&setelem_parse_ctx.stmt_list, &expr->stmt_list);
+ list_splice_tail_init(&setelem_parse_ctx.stmt_list, &expr->stmt_list);
if (flags & NFT_SET_ELEM_INTERVAL_END) {
expr->flags |= EXPR_F_INTERVAL_END;
diff --git a/tests/shell/testcases/maps/0013map_0 b/tests/shell/testcases/maps/0013map_0
new file mode 100755
index 00000000..70d7fd3b
--- /dev/null
+++ b/tests/shell/testcases/maps/0013map_0
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+RULESET="
+flush ruleset
+
+add table ip filter
+add chain ip filter FORWARD { type filter hook forward priority 0; policy drop; }
+add map ip filter forwport { type ipv4_addr . inet_proto . inet_service: verdict; flags interval; counter; }
+add rule ip filter FORWARD iifname enp0s8 ip daddr . ip protocol . th dport vmap @forwport counter
+add element ip filter forwport { 10.133.89.138 . tcp . 8081: accept }"
+
+$NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/maps/dumps/0013map_0.nft b/tests/shell/testcases/maps/dumps/0013map_0.nft
new file mode 100644
index 00000000..1455877d
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/0013map_0.nft
@@ -0,0 +1,13 @@
+table ip filter {
+ map forwport {
+ type ipv4_addr . inet_proto . inet_service : verdict
+ flags interval
+ counter
+ elements = { 10.133.89.138 . tcp . 8081 counter packets 0 bytes 0 : accept }
+ }
+
+ chain FORWARD {
+ type filter hook forward priority filter; policy drop;
+ iifname "enp0s8" ip daddr . ip protocol . th dport vmap @forwport counter packets 0 bytes 0
+ }
+}
--
2.33.0

View File

@ -0,0 +1,164 @@
From c009df1fded60c64075493c875873f05606f17ef Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Sun, 21 Nov 2021 23:33:09 +0100
Subject: parser: split tcp option rules
At this time the parser will accept nonsensical input like
tcp option mss left 2
which will be treated as 'tcp option maxseg size 2'.
This is because the enum space overlaps.
Split the rules so that 'tcp option mss' will only
accept field names specific to the mss/maxseg option kind.
Signed-off-by: Florian Westphal <fw@strlen.de>
(cherry picked from commit 46168852c03d73c29b557c93029dc512ca6e233a)
Conflict:change context and add KIND type in parser_bison.y
Reference:https://git.netfilter.org/nftables/commit/?id=c009df1fded60c64075493c875873f05606f17ef
---
src/parser_bison.y | 80 +++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 61 insertions(+), 19 deletions(-)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 26060985..fca79132 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -187,6 +187,10 @@ int nft_lex(void *, void *, void *);
struct handle_spec handle_spec;
struct position_spec position_spec;
struct prio_spec prio_spec;
+ struct tcp_kind_field {
+ uint16_t kind; /* must allow > 255 for SACK1, 2.. hack */
+ uint8_t field;
+ } tcp_kind_field;
}
%token TOKEN_EOF 0 "end of file"
@@ -873,7 +877,10 @@ int nft_lex(void *, void *, void *);
%type <expr> tcp_hdr_expr
%destructor { expr_free($$); } tcp_hdr_expr
%type <val> tcp_hdr_field
-%type <val> tcp_hdr_option_type tcp_hdr_option_field
+%type <val> tcp_hdr_option_type
+%type <val> tcp_hdr_option_sack
+%type <val> tcpopt_field_maxseg tcpopt_field_sack tcpopt_field_tsopt tcpopt_field_window
+%type <tcp_kind_field> tcp_hdr_option_kind_and_field
%type <expr> boolean_expr
%destructor { expr_free($$); } boolean_expr
@@ -5477,15 +5484,15 @@ tcp_hdr_expr : TCP tcp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
}
- | TCP OPTION tcp_hdr_option_type tcp_hdr_option_field
- {
- $$ = tcpopt_expr_alloc(&@$, $3, $4);
- }
| TCP OPTION tcp_hdr_option_type
{
$$ = tcpopt_expr_alloc(&@$, $3, TCPOPT_COMMON_KIND);
$$->exthdr.flags = NFT_EXTHDR_F_PRESENT;
}
+ | TCP OPTION tcp_hdr_option_kind_and_field
+ {
+ $$ = tcpopt_expr_alloc(&@$, $3.kind, $3.field);
+ }
| TCP OPTION AT tcp_hdr_option_type COMMA NUM COMMA NUM
{
$$ = tcpopt_expr_alloc(&@$, $4, 0);
@@ -5505,19 +5512,53 @@ tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
| URGPTR { $$ = TCPHDR_URGPTR; }
;
-tcp_hdr_option_type : EOL { $$ = TCPOPT_KIND_EOL; }
- | NOP { $$ = TCPOPT_KIND_NOP; }
- | MSS { $$ = TCPOPT_KIND_MAXSEG; }
- | WINDOW { $$ = TCPOPT_KIND_WINDOW; }
- | SACK_PERM { $$ = TCPOPT_KIND_SACK_PERMITTED; }
- | SACK { $$ = TCPOPT_KIND_SACK; }
+tcp_hdr_option_kind_and_field : MSS tcpopt_field_maxseg
+ {
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_MAXSEG, .field = $2 };
+ $$ = kind_field;
+ }
+ | tcp_hdr_option_sack tcpopt_field_sack
+ {
+ struct tcp_kind_field kind_field = { .kind = $1, .field = $2 };
+ $$ = kind_field;
+ }
+ | WINDOW tcpopt_field_window
+ {
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_WINDOW, .field = $2 };
+ $$ = kind_field;
+ }
+ | TIMESTAMP tcpopt_field_tsopt
+ {
+ struct tcp_kind_field kind_field = { .kind = TCPOPT_KIND_TIMESTAMP, .field = $2 };
+ $$ = kind_field;
+ }
+ | tcp_hdr_option_type LENGTH
+ {
+ struct tcp_kind_field kind_field = { .kind = $1, .field = TCPOPT_COMMON_LENGTH };
+ $$ = kind_field;
+ }
+ | tcp_hdr_option_type KIND
+ { struct tcp_kind_field kind_field = { .kind = $1, .field = TCPOPT_COMMON_KIND };
+ $$ = kind_field;
+ }
+ ;
+
+tcp_hdr_option_sack : SACK { $$ = TCPOPT_KIND_SACK; }
| SACK0 { $$ = TCPOPT_KIND_SACK; }
| SACK1 { $$ = TCPOPT_KIND_SACK1; }
| SACK2 { $$ = TCPOPT_KIND_SACK2; }
| SACK3 { $$ = TCPOPT_KIND_SACK3; }
- | ECHO { $$ = TCPOPT_KIND_ECHO; }
- | TIMESTAMP { $$ = TCPOPT_KIND_TIMESTAMP; }
- | NUM {
+ ;
+
+tcp_hdr_option_type : ECHO { $$ = TCPOPT_KIND_ECHO; }
+ | EOL { $$ = TCPOPT_KIND_EOL; }
+ | MSS { $$ = TCPOPT_KIND_MAXSEG; }
+ | NOP { $$ = TCPOPT_KIND_NOP; }
+ | SACK_PERM { $$ = TCPOPT_KIND_SACK_PERMITTED; }
+ | TIMESTAMP { $$ = TCPOPT_KIND_TIMESTAMP; }
+ | WINDOW { $$ = TCPOPT_KIND_WINDOW; }
+ | tcp_hdr_option_sack { $$ = $1; }
+ | NUM {
if ($1 > 255) {
erec_queue(error(&@1, "value too large"), state->msgs);
YYERROR;
@@ -5526,16 +5563,20 @@ tcp_hdr_option_type : EOL { $$ = TCPOPT_KIND_EOL; }
}
;
-tcp_hdr_option_field : KIND { $$ = TCPOPT_COMMON_KIND; }
- | LENGTH { $$ = TCPOPT_COMMON_LENGTH; }
- | SIZE { $$ = TCPOPT_MAXSEG_SIZE; }
- | COUNT { $$ = TCPOPT_WINDOW_COUNT; }
- | LEFT { $$ = TCPOPT_SACK_LEFT; }
+tcpopt_field_sack : LEFT { $$ = TCPOPT_SACK_LEFT; }
| RIGHT { $$ = TCPOPT_SACK_RIGHT; }
- | TSVAL { $$ = TCPOPT_TS_TSVAL; }
+ ;
+
+tcpopt_field_window : COUNT { $$ = TCPOPT_WINDOW_COUNT; }
+ ;
+
+tcpopt_field_tsopt : TSVAL { $$ = TCPOPT_TS_TSVAL; }
| TSECR { $$ = TCPOPT_TS_TSECR; }
;
+tcpopt_field_maxseg : SIZE { $$ = TCPOPT_MAXSEG_SIZE; }
+ ;
+
dccp_hdr_expr : DCCP dccp_hdr_field
{
$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
--
cgit v1.2.3

View File

@ -0,0 +1,264 @@
From 47e18c0eba51a538e1110322d1a9248b0501d7c8 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 19 Aug 2024 21:34:49 +0200
Subject: parser_json: fix handle memleak from error path
Based on patch from Sebastian Walz.
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:change context and delete a part code in json_parse_cmd_add_chain
Reference:https://git.netfilter.org/nftables/commit/?id=47e18c0eba51a538e1110322d1a9248b0501d7c8
---
src/parser_json.c | 93 ++++++++++++++++++++++++++++---------------------------
1 file changed, 47 insertions(+), 46 deletions(-)
diff --git a/src/parser_json.c b/src/parser_json.c
index 8ca44efb..d18188d8 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -3168,8 +3168,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
chain->hook.name = chain_hookname_lookup(hookstr);
if (!chain->hook.name) {
json_error(ctx, "Invalid chain hook '%s'.", hookstr);
- chain_free(chain);
- return NULL;
+ goto err_free_chain;
}
if (!json_unpack(root, "{s:s}", "dev", &name)) {
@@ -3187,8 +3185,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
chain->policy = parse_policy(policy);
if (!chain->policy) {
json_error(ctx, "Unknown policy '%s'.", policy);
- chain_free(chain);
- return NULL;
+ goto err_free_chain;
}
}
@@ -3197,6 +3194,11 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root,
handle_merge(&chain->handle, &h);
return cmd_alloc(op, obj, &h, int_loc, chain);
+
+err_free_chain:
+ chain_free(chain);
+ handle_free(&h);
+ return NULL;
}
static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
@@ -3236,6 +3238,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
if (!json_is_array(tmp)) {
json_error(ctx, "Value of property \"expr\" must be an array.");
+ handle_free(&h);
return NULL;
}
@@ -3255,16 +3258,14 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
if (!json_is_object(value)) {
json_error(ctx, "Unexpected expr array element of type %s, expected object.",
json_typename(value));
- rule_free(rule);
- return NULL;
+ goto err_free_rule;
}
stmt = json_parse_stmt(ctx, value);
if (!stmt) {
json_error(ctx, "Parsing expr array at index %zd failed.", index);
- rule_free(rule);
- return NULL;
+ goto err_free_rule;
}
rule_stmt_append(rule, stmt);
@@ -3274,6 +3275,11 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root,
json_object_del(root, "handle");
return cmd_alloc(op, obj, &h, int_loc, rule);
+
+err_free_rule:
+ rule_free(rule);
+ handle_free(&h);
+ return NULL;
}
static int string_to_nft_object(const char *str)
@@ -3654,8 +3660,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
if (ret < 0 || ret >= (int)sizeof(obj->secmark.ctx)) {
json_error(ctx, "Invalid secmark context '%s', max length is %zu.",
tmp, sizeof(obj->secmark.ctx));
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
}
break;
@@ -3671,8 +3676,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
ret >= (int)sizeof(obj->ct_helper.name)) {
json_error(ctx, "Invalid CT helper type '%s', max length is %zu.",
tmp, sizeof(obj->ct_helper.name));
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
}
if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
@@ -3682,15 +3686,13 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
obj->ct_helper.l4proto = IPPROTO_UDP;
} else {
json_error(ctx, "Invalid ct helper protocol '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
}
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
parse_family(tmp, &l3proto)) {
json_error(ctx, "Invalid ct helper l3proto '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
obj->ct_helper.l3proto = l3proto;
break;
@@ -3704,23 +3706,19 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
obj->ct_timeout.l4proto = IPPROTO_UDP;
} else {
json_error(ctx, "Invalid ct timeout protocol '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
}
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
parse_family(tmp, &l3proto)) {
json_error(ctx, "Invalid ct timeout l3proto '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
obj->ct_timeout.l3proto = l3proto;
init_list_head(&obj->ct_timeout.timeout_list);
- if (json_parse_ct_timeout_policy(ctx, root, obj)) {
- obj_free(obj);
- return NULL;
- }
+ if (json_parse_ct_timeout_policy(ctx, root, obj))
+ goto err_free_obj;
break;
case NFT_OBJECT_CT_EXPECT:
cmd_obj = CMD_OBJ_CT_EXPECT;
@@ -3728,8 +3726,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
if (!json_unpack(root, "{s:s}", "l3proto", &tmp) &&
parse_family(tmp, &l3proto)) {
json_error(ctx, "Invalid ct expectation l3proto '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
obj->ct_expect.l3proto = l3proto;
if (!json_unpack(root, "{s:s}", "protocol", &tmp)) {
@@ -3739,8 +3736,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
obj->ct_expect.l4proto = IPPROTO_UDP;
} else {
json_error(ctx, "Invalid ct expectation protocol '%s'.", tmp);
- obj_free(obj);
- return NULL;
+ goto err_free_obj;
}
}
if (!json_unpack(root, "{s:i}", "dport", &i))
@@ -3754,10 +3750,9 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
obj->type = NFT_OBJECT_LIMIT;
if (json_unpack_err(ctx, root, "{s:I, s:s}",
"rate", &obj->limit.rate,
- "per", &tmp)) {
- obj_free(obj);
- return NULL;
- }
+ "per", &tmp))
+ goto err_free_obj;
+
json_unpack(root, "{s:s}", "rate_unit", &rate_unit);
json_unpack(root, "{s:b}", "inv", &inv);
json_unpack(root, "{s:I}", "burst", &obj->limit.burst);
@@ -3778,20 +3773,18 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
case CMD_OBJ_SYNPROXY:
obj->type = NFT_OBJECT_SYNPROXY;
if (json_unpack_err(ctx, root, "{s:i, s:i}",
- "mss", &i, "wscale", &j)) {
- obj_free(obj);
- return NULL;
- }
+ "mss", &i, "wscale", &j))
+ goto err_free_obj;
+
obj->synproxy.mss = i;
obj->synproxy.wscale = j;
obj->synproxy.flags |= NF_SYNPROXY_OPT_MSS;
obj->synproxy.flags |= NF_SYNPROXY_OPT_WSCALE;
if (!json_unpack(root, "{s:o}", "flags", &jflags)) {
flags = json_parse_synproxy_flags(ctx, jflags);
- if (flags < 0) {
- obj_free(obj);
- return NULL;
- }
+ if (flags < 0)
+ goto err_free_obj;
+
obj->synproxy.flags |= flags;
}
break;
@@ -3803,6 +3796,11 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx,
json_object_del(root, "handle");
return cmd_alloc(op, cmd_obj, &h, int_loc, obj);
+
+err_free_obj:
+ obj_free(obj);
+ handle_free(&h);
+ return NULL;
}
static struct cmd *json_parse_cmd_add(struct json_ctx *ctx,
@@ -3917,8 +3915,7 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
if (!json_is_object(value)) {
json_error(ctx, "Unexpected expr array element of type %s, expected object.",
json_typename(value));
- rule_free(rule);
- return NULL;
+ goto err_free_replace;
}
stmt = json_parse_stmt(ctx, value);
@@ -3926,8 +3923,7 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
if (!stmt) {
json_error(ctx, "Parsing expr array at index %zd failed.",
index);
- rule_free(rule);
- return NULL;
+ goto err_free_replace;
}
rule_stmt_append(rule, stmt);
@@ -3937,6 +3933,11 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx,
json_object_del(root, "handle");
return cmd_alloc(op, CMD_OBJ_RULE, &h, int_loc, rule);
+
+err_free_replace:
+ rule_free(rule);
+ handle_free(&h);
+ return NULL;
}
static struct cmd *json_parse_cmd_list_multiple(struct json_ctx *ctx,
--
cgit v1.2.3

View File

@ -0,0 +1,38 @@
From bae7b4d283826efbeb28c21aecd7b355e86da170 Mon Sep 17 00:00:00 2001
From: "Sebastian Walz (sivizius)" <sebastian.walz@secunet.com>
Date: Mon, 19 Aug 2024 20:11:44 +0200
Subject: parser_json: fix several expression memleaks from error path
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
Signed-off-by: Sebastian Walz (sivizius) <sebastian.walz@secunet.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:delete change about json_parse_optstrip_stmt
Reference:https://git.netfilter.org/nftables/commit/?id=bae7b4d283826efbeb28c21aecd7b355e86da170
---
src/parser_json.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/parser_json.c b/src/parser_json.c
index fc20fe29..8ca44efb 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1308,6 +1308,7 @@ static struct expr *json_parse_range_expr(struct json_ctx *ctx,
expr_high = json_parse_primary_expr(ctx, high);
if (!expr_high) {
json_error(ctx, "Invalid high value in range expression.");
+ expr_free(expr_low);
return NULL;
}
return range_expr_alloc(int_loc, expr_low, expr_high);
@@ -1889,6 +1890,8 @@ static struct stmt *json_parse_mangle_stmt(struct json_ctx *ctx,
return stmt;
default:
json_error(ctx, "Invalid mangle statement key expression type.");
+ expr_free(key);
+ expr_free(value);
return NULL;
}
}
--
cgit v1.2.3

View File

@ -0,0 +1,43 @@
From 46700fbdbbbaab0d7db716fce3a438334c58ac9e Mon Sep 17 00:00:00 2001
From: "Sebastian Walz (sivizius)" <sebastian.walz@secunet.com>
Date: Mon, 19 Aug 2024 19:58:14 +0200
Subject: parser_json: release buffer returned by json_dumps
The signature of `json_dumps` is:
`char *json_dumps(const json_t *json, size_t flags)`:
It will return a pointer to an owned string, the caller must free it.
However, `json_error` just borrows the string to format it as `%s`, but
after printing the formatted error message, the pointer to the string is
lost and thus never freed.
Fixes: 586ad210368b ("libnftables: Implement JSON parser")
Signed-off-by: Sebastian Walz (sivizius) <sebastian.walz@secunet.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Conflict:delete change about json_parse_cmd_add_set;change free_const to xfree
Reference:https://git.netfilter.org/nftables/commit/?id=46700fbdbbbaab0d7db716fce3a438334c58ac9e
---
src/parser_json.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/parser_json.c b/src/parser_json.c
index 4912d360..fc20fe29 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -181,8 +181,11 @@ static int json_unpack_stmt(struct json_ctx *ctx, json_t *root,
assert(value);
if (json_object_size(root) != 1) {
+ const char *dump = json_dumps(root, 0);
+
json_error(ctx, "Malformed object (too many properties): '%s'.",
- json_dumps(root, 0));
+ dump);
+ xfree(dump);
return 1;
}
--
cgit v1.2.3

View File

@ -0,0 +1,76 @@
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: 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>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=ff6135270616ccf4712990246cae850e64253516
---
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;
}
--
cgit v1.2.3

View File

@ -0,0 +1,172 @@
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: 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>
Conflict:change rule.h evaluate.c netlink_linearize.c
Reference:https://git.netfilter.org/nftables/commit/?id=dcb199544563ded462cb7151134278f82a9e6cfd
---
include/expression.h | 1 +
include/rule.h | 2 +
src/evaluate.c | 39 ++++++++++++++++++-
src/netlink_linearize.c | 7 +++-
.../bogons/nft-f/huge_binop_expr_chain_crash | 5 +++
5 files changed, 50 insertions(+), 4 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 778998f..c89f24e 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -11,6 +11,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 be31695..4830691 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -747,6 +747,7 @@ void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc);
* @rule: current rule
* @set: current set
* @stmt: current statement
+ * @recursion: expr evaluation recursion counter
* @cache: cache context
* @debug_mask: debugging bitmask
* @ectx: expression context
@@ -760,6 +761,7 @@ struct eval_ctx {
struct rule *rule;
struct set *set;
struct stmt *stmt;
+ uint32_t recursion;
struct expr_ctx ectx;
struct proto_ctx pctx;
};
diff --git a/src/evaluate.c b/src/evaluate.c
index 6163ba6..1aa3d7e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1173,6 +1173,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];
+ 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;
@@ -1222,14 +1229,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 f271b11..1c43ccc 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -625,10 +625,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;
@@ -640,8 +640,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 0000000..8d1da72
--- /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
+ }
+}
--
cgit v1.2.3

View File

@ -0,0 +1,79 @@
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>
Conflict:delete evaluate.c change and delete new test stack_overflow_via_large_concat_expr and change parser_bison.y context
Reference:https://git.netfilter.org/nftables/commit/?id=ef10d65db278d77208e960d210a1f4f532ebb552
---
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/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
{
+ 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_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

View File

@ -0,0 +1,47 @@
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>
Conflict: NA
Reference:https://git.netfilter.org/nftables/commit/?id=c9f934ca446de5041ce6f19e4ee6a0c74b120186
---
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

View File

@ -0,0 +1,135 @@
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>
Conflict: change concat_range_abort
Reference:https://git.netfilter.org/nftables/commit/?id=b237aeff41840f0c7968d02ed3d461fa9fa8fb70
---
.../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 . 0x123434 : 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

View File

@ -0,0 +1,97 @@
From 1fc78397e9a1fb5e41841b8b4e92a9eb9536c6f1 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Wed, 10 Jul 2024 02:33:37 +0200
Subject: tests: shell: connect chains to hook point
These tests should fail because they contain a loop or exceed the jump stack.
But this depends on the kernel validating chains that are not bound to any
basechain/hook point.
Wire up the initial chain to filter type.
Without this tests will start to fail when kernel stops validating
chains that are not reachable by any base chain.
Signed-off-by: Florian Westphal <fw@strlen.de>
Conflict:delete the file that we don't have
Reference:https://git.netfilter.org/nftables/commit/?id=1fc78397e9a1fb5e41841b8b4e92a9eb9536c6f1
---
tests/shell/testcases/chains/0003jump_loop_1 | 3 ++-
tests/shell/testcases/chains/0010endless_jump_loop_1 | 2 +-
tests/shell/testcases/chains/0011endless_jump_loop_1 | 2 +-
tests/shell/testcases/chains/0018check_jump_loop_1 | 2 +-
tests/shell/testcases/transactions/0023rule_1 | 2 +-
5 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/tests/shell/testcases/chains/0003jump_loop_1 b/tests/shell/testcases/chains/0003jump_loop_1
index 80e243f0..1a8eaf68 100755
--- a/tests/shell/testcases/chains/0003jump_loop_1
+++ b/tests/shell/testcases/chains/0003jump_loop_1
@@ -5,8 +5,9 @@ set -e
MAX_JUMPS=16
$NFT add table t
+$NFT "add chain t c1 { type filter hook prerouting priority 0; }"
-for i in $(seq 1 $MAX_JUMPS)
+for i in $(seq 2 $MAX_JUMPS)
do
$NFT add chain t c${i}
done
diff --git a/tests/shell/testcases/chains/0010endless_jump_loop_1 b/tests/shell/testcases/chains/0010endless_jump_loop_1
index 5d3ef239..6000e5d7 100755
--- a/tests/shell/testcases/chains/0010endless_jump_loop_1
+++ b/tests/shell/testcases/chains/0010endless_jump_loop_1
@@ -3,7 +3,7 @@
set -e
$NFT add table t
-$NFT add chain t c
+$NFT add chain "t c { type filter hook input priority 0; }"
# kernel should return ELOOP
$NFT add rule t c tcp dport vmap {1 : jump c} 2>/dev/null || exit 0
diff --git a/tests/shell/testcases/chains/0011endless_jump_loop_1 b/tests/shell/testcases/chains/0011endless_jump_loop_1
index d75932d7..66abf8d0 100755
--- a/tests/shell/testcases/chains/0011endless_jump_loop_1
+++ b/tests/shell/testcases/chains/0011endless_jump_loop_1
@@ -3,7 +3,7 @@
set -e
$NFT add table t
-$NFT add chain t c1
+$NFT add chain "t c1 { type filter hook forward priority 0; }"
$NFT add chain t c2
$NFT add map t m {type inet_service : verdict \;}
$NFT add element t m {2 : jump c2}
diff --git a/tests/shell/testcases/chains/0018check_jump_loop_1 b/tests/shell/testcases/chains/0018check_jump_loop_1
index b87520f2..1e674d3d 100755
--- a/tests/shell/testcases/chains/0018check_jump_loop_1
+++ b/tests/shell/testcases/chains/0018check_jump_loop_1
@@ -3,7 +3,7 @@
set -e
$NFT add table ip filter
-$NFT add chain ip filter ap1
+$NFT add chain ip filter ap1 "{ type filter hook input priority 0; }"
$NFT add chain ip filter ap2
$NFT add rule ip filter ap1 jump ap2
diff --git a/tests/shell/testcases/transactions/0023rule_1 b/tests/shell/testcases/transactions/0023rule_1
index e58c088c..863bcde4 100755
--- a/tests/shell/testcases/transactions/0023rule_1
+++ b/tests/shell/testcases/transactions/0023rule_1
@@ -1,7 +1,7 @@
#!/bin/bash
RULESET="add table x
-add chain x y
+add chain x y { type filter hook input priority 0; }
add rule x y jump y"
# kernel must return ELOOP
--
cgit v1.2.3

View File

@ -1,6 +1,6 @@
Name: nftables
Version: 1.0.0
Release: 10
Release: 15
Epoch: 1
Summary: A subsystem of the Linux kernel processing network data
License: GPLv2
@ -75,6 +75,38 @@ Patch59: backport-evaluate-tproxy-move-range-error-checks-after-arg-ev.pa
Patch60: backport-evaluate-error-out-when-store-needs-more-than-one-12.patch
Patch61: backport-rule-fix-sym-refcount-assertion.patch
Patch62: backport-evaluate-handle-invalid-mapping-expressions-gracefully.patch
Patch63: backport-evaluate-error-out-if-basetypes-are-different.patch
Patch64: backport-evaluate-reject-attempt-to-update-a-set.patch
Patch65: backport-evaluate-guard-against-NULL-basetype.patch
Patch66: backport-evaluate-release-mpz-type-in-expr_evaluate_list-error-path.patch
Patch67: backport-expression-missing-line-in-describe-command-with-invalid-expression.patch
Patch68: backport-evaluate-disable-meta-set-with-ranges.patch
Patch69: backport-src-reject-large-raw-payload-and-concat-expressions.patch
Patch70: backport-evaluate-fix-stack-overflow-with-huge-priority-string.patch
Patch71: backport-tcpopt-don-t-create-exthdr-expression-without-datatype.patch
Patch72: backport-src-do-not-allow-to-chain-more-than-16-binops.patch
Patch73: backport-rule-fix-ASAN-errors-in-chain-priority-to-textual-names.patch
Patch74: backport-tests-shell-add-regression-test-for-double-free-crash-bug.patch
Patch75: backport-evaluate-handle-invalid-mapping-expressions-in-stateful-object-statements-gracefully.patch
Patch76: backport-evaluate-Fix-incorrect-checking-the-base-variable-in-case-of-IPV6.patch
Patch77: backport-netlink-reset-temporary-set-element-stmt-list-after-list-splice.patch
Patch78: backport-parser-split-tcp-option-rules.patch
Patch79: backport-cache-prepare-nft_cache_evaluate-to-return-error.patch
Patch80: backport-ct-timeout-fix-list-object-x-vs-list-objects-in-table-confusion.patch
Patch81: backport-ct-expectation-fix-list-object-x-vs-list-objects-in-table-confusion.patch
Patch82: backport-tests-shell-connect-chains-to-hook-point.patch
Patch83: backport-parser_json-release-buffer-returned-by-json_dumps.patch
Patch84: backport-parser_json-fix-handle-memleak-from-error-path.patch
Patch85: backport-parser_json-fix-several-expression-memleaks-from-error-path.patch
Patch86: backport-libnftables-Zero-ctx-vars-after-freeing-it.patch
Patch87: backport-cache-add-helper-function-to-fill-up-the-rule-cache.patch
Patch88: backport-cache-release-pending-rules-when-chain-binding-lookup-fails.patch
BuildRequires: gcc flex bison libmnl-devel gmp-devel readline-devel libnftnl-devel docbook2X systemd
BuildRequires: iptables-devel jansson-devel python3-devel
BuildRequires: chrpath
@ -173,6 +205,60 @@ echo "%{_libdir}" > %{buildroot}/etc/ld.so.conf.d/%{name}-%{_arch}.conf
%{python3_sitelib}/nftables/
%changelog
* Mon Jan 27 2025 yanglu <yanglu72@h-partners.com> - 1:1.0.0-15
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:Optimize the cache to fix firewalld
* Wed Dec 11 2024 gaihuiying <eaglegai@163.com> - 1:1.0.0-14
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:backport upstream patches
parser_json: release buffer returned by json_dumps
parser_json: fix handle memleak from error path
parser_json: fix several expression memleaks from error path
libnftables: Zero ctx->vars after freeing it
* Tue Dec 10 2024 gaihuiying <eaglegai@163.com> - 1:1.0.0-13
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:parser: split tcp option rules
cache: prepare nft_cache_evaluate() to return error
ct timeout: fix 'list object x' vs. 'list objects in table' confusion
ct expectation: fix 'list object x' vs. 'list objects in table' confusion
tests: shell: connect chains to hook point
* Wed Sep 25 2024 gaihuiying <eaglegai@163.com> - 1:1.0.0-12
- 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
netlink: reset temporary set element stmt list after list splice
* Wed Jun 26 2024 gaihuiying <eaglegai@163.com> - 1:1.0.0-11
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:backport upstream patches
evaluate: error out if basetypes are different
evaluate: guard against NULL basetype
evaluate: handle invalid mapping expressions gracefully
evaluate: reject attempt to update a set
evaluate: release mpz type in expr_evaluate_list() error path
expression: missing line in describe command with invalid expression
Thu Apr 18 2024 lingsheng <lingsheng1@h-partners.com> - 1:1.0.0-10
- Type:bugfix
- CVE:NA