94 lines
3.0 KiB
Diff
94 lines
3.0 KiB
Diff
From 3bcd138f2baa8578caf261768e67b58ff3372f91 Mon Sep 17 00:00:00 2001
|
|
From: Phil Sutter <psutter@redhat.com>
|
|
Date: Fri, 17 Jul 2026 11:14:03 +0200
|
|
Subject: [PATCH] json: Fix for memleak in __binop_expr_json
|
|
|
|
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
|
Upstream Status: nftables commit a0a15e4dd0576bc4efd9b01fdd4ee1c565effac9
|
|
|
|
commit a0a15e4dd0576bc4efd9b01fdd4ee1c565effac9
|
|
Author: Phil Sutter <phil@nwl.cc>
|
|
Date: Wed Apr 24 23:35:00 2024 +0200
|
|
|
|
json: Fix for memleak in __binop_expr_json
|
|
|
|
When merging the JSON arrays generated for LHS and RHS of nested binop
|
|
expressions, the emptied array objects leak if their reference is not
|
|
decremented.
|
|
|
|
Fix this and tidy up other spots which did it right already by
|
|
introducing a json_array_extend wrapper.
|
|
|
|
Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
Fixes: 0ac39384fd9e4 ("json: Accept more than two operands in binary expressions")
|
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
---
|
|
src/json.c | 24 ++++++++++++++++--------
|
|
1 file changed, 16 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/src/json.c b/src/json.c
|
|
index 089c251..516045b 100644
|
|
--- a/src/json.c
|
|
+++ b/src/json.c
|
|
@@ -42,6 +42,15 @@
|
|
})
|
|
#endif
|
|
|
|
+static int json_array_extend_new(json_t *array, json_t *other_array)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = json_array_extend(array, other_array);
|
|
+ json_decref(other_array);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static json_t *expr_print_json(const struct expr *expr, struct output_ctx *octx)
|
|
{
|
|
const struct expr_ops *ops;
|
|
@@ -557,8 +566,10 @@ __binop_expr_json(int op, const struct expr *expr, struct output_ctx *octx)
|
|
json_t *a = json_array();
|
|
|
|
if (expr->etype == EXPR_BINOP && expr->op == op) {
|
|
- json_array_extend(a, __binop_expr_json(op, expr->left, octx));
|
|
- json_array_extend(a, __binop_expr_json(op, expr->right, octx));
|
|
+ json_array_extend_new(a,
|
|
+ __binop_expr_json(op, expr->left, octx));
|
|
+ json_array_extend_new(a,
|
|
+ __binop_expr_json(op, expr->right, octx));
|
|
} else {
|
|
json_array_append_new(a, expr_print_json(expr, octx));
|
|
}
|
|
@@ -1761,8 +1772,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
|
|
}
|
|
}
|
|
|
|
- json_array_extend(root, rules);
|
|
- json_decref(rules);
|
|
+ json_array_extend_new(root, rules);
|
|
|
|
return root;
|
|
}
|
|
@@ -1770,7 +1780,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
|
|
static json_t *do_list_ruleset_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
|
{
|
|
unsigned int family = cmd->handle.family;
|
|
- json_t *root = json_array(), *tmp;
|
|
+ json_t *root = json_array();
|
|
struct table *table;
|
|
|
|
list_for_each_entry(table, &ctx->nft->cache.table_cache.list, cache.list) {
|
|
@@ -1778,9 +1788,7 @@ static json_t *do_list_ruleset_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
|
table->handle.family != family)
|
|
continue;
|
|
|
|
- tmp = table_print_json_full(ctx, table);
|
|
- json_array_extend(root, tmp);
|
|
- json_decref(tmp);
|
|
+ json_array_extend_new(root, table_print_json_full(ctx, table));
|
|
}
|
|
|
|
return root;
|