summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2020-01-20 14:48:26 +0100
committerPhil Sutter <phil@nwl.cc>2020-01-22 09:01:01 +0100
commite957bd9f10d5e36671a0b0398e2037fc6201275b (patch)
tree87c9edef1c3d3bc8e3474508265e0bead92bba23 /src/netlink_delinearize.c
parentc3f6be3f2dcedf6d79751c0b975315ebc3184364 (diff)
netlink: Fix leaks in netlink_parse_cmp()
This fixes several problems at once: * Err path would leak expr 'right' in two places and 'left' in one. * Concat case would leak 'right' by overwriting the pointer. Introduce a temporary variable to hold the new pointer. Fixes: 6377380bc265f ("netlink_delinearize: handle relational and lookup concat expressions") Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r--src/netlink_delinearize.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 06a0312b..88dbd5a8 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -274,7 +274,7 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx,
{
struct nft_data_delinearize nld;
enum nft_registers sreg;
- struct expr *expr, *left, *right;
+ struct expr *expr, *left, *right, *tmp;
enum ops op;
sreg = netlink_parse_register(nle, NFTNL_EXPR_CMP_SREG);
@@ -291,19 +291,26 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx,
if (left->len > right->len &&
expr_basetype(left) != &string_type) {
- return netlink_error(ctx, loc, "Relational expression size mismatch");
+ netlink_error(ctx, loc, "Relational expression size mismatch");
+ goto err_free;
} else if (left->len > 0 && left->len < right->len) {
expr_free(left);
left = netlink_parse_concat_expr(ctx, loc, sreg, right->len);
if (left == NULL)
- return;
- right = netlink_parse_concat_data(ctx, loc, sreg, right->len, right);
- if (right == NULL)
- return;
+ goto err_free;
+ tmp = netlink_parse_concat_data(ctx, loc, sreg, right->len, right);
+ if (tmp == NULL)
+ goto err_free;
+ expr_free(right);
+ right = tmp;
}
expr = relational_expr_alloc(loc, op, left, right);
ctx->stmt = expr_stmt_alloc(loc, expr);
+ return;
+err_free:
+ expr_free(left);
+ expr_free(right);
}
static void netlink_parse_lookup(struct netlink_parse_ctx *ctx,