|
|
f1d1c0 |
From 6ecccc872b9cbed921af10e32d1a628eb6a74c01 Mon Sep 17 00:00:00 2001
|
|
|
f1d1c0 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
f1d1c0 |
Date: Mon, 27 Jan 2020 16:11:41 +0100
|
|
|
f1d1c0 |
Subject: [PATCH] netlink: Fix leaks in netlink_parse_cmp()
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1793030
|
|
|
f1d1c0 |
Upstream Status: nftables commit e957bd9f10d5e
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
commit e957bd9f10d5e36671a0b0398e2037fc6201275b
|
|
|
f1d1c0 |
Author: Phil Sutter <phil@nwl.cc>
|
|
|
f1d1c0 |
Date: Mon Jan 20 14:48:26 2020 +0100
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
netlink: Fix leaks in netlink_parse_cmp()
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
This fixes several problems at once:
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
* Err path would leak expr 'right' in two places and 'left' in one.
|
|
|
f1d1c0 |
* Concat case would leak 'right' by overwriting the pointer. Introduce a
|
|
|
f1d1c0 |
temporary variable to hold the new pointer.
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
Fixes: 6377380bc265f ("netlink_delinearize: handle relational and lookup concat expressions")
|
|
|
f1d1c0 |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
f1d1c0 |
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
f1d1c0 |
---
|
|
|
f1d1c0 |
src/netlink_delinearize.c | 19 +++++++++++++------
|
|
|
f1d1c0 |
1 file changed, 13 insertions(+), 6 deletions(-)
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
|
|
|
f1d1c0 |
index 06a0312..88dbd5a 100644
|
|
|
f1d1c0 |
--- a/src/netlink_delinearize.c
|
|
|
f1d1c0 |
+++ b/src/netlink_delinearize.c
|
|
|
f1d1c0 |
@@ -274,7 +274,7 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx,
|
|
|
f1d1c0 |
{
|
|
|
f1d1c0 |
struct nft_data_delinearize nld;
|
|
|
f1d1c0 |
enum nft_registers sreg;
|
|
|
f1d1c0 |
- struct expr *expr, *left, *right;
|
|
|
f1d1c0 |
+ struct expr *expr, *left, *right, *tmp;
|
|
|
f1d1c0 |
enum ops op;
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
sreg = netlink_parse_register(nle, NFTNL_EXPR_CMP_SREG);
|
|
|
f1d1c0 |
@@ -291,19 +291,26 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx,
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
if (left->len > right->len &&
|
|
|
f1d1c0 |
expr_basetype(left) != &string_type) {
|
|
|
f1d1c0 |
- return netlink_error(ctx, loc, "Relational expression size mismatch");
|
|
|
f1d1c0 |
+ netlink_error(ctx, loc, "Relational expression size mismatch");
|
|
|
f1d1c0 |
+ goto err_free;
|
|
|
f1d1c0 |
} else if (left->len > 0 && left->len < right->len) {
|
|
|
f1d1c0 |
expr_free(left);
|
|
|
f1d1c0 |
left = netlink_parse_concat_expr(ctx, loc, sreg, right->len);
|
|
|
f1d1c0 |
if (left == NULL)
|
|
|
f1d1c0 |
- return;
|
|
|
f1d1c0 |
- right = netlink_parse_concat_data(ctx, loc, sreg, right->len, right);
|
|
|
f1d1c0 |
- if (right == NULL)
|
|
|
f1d1c0 |
- return;
|
|
|
f1d1c0 |
+ goto err_free;
|
|
|
f1d1c0 |
+ tmp = netlink_parse_concat_data(ctx, loc, sreg, right->len, right);
|
|
|
f1d1c0 |
+ if (tmp == NULL)
|
|
|
f1d1c0 |
+ goto err_free;
|
|
|
f1d1c0 |
+ expr_free(right);
|
|
|
f1d1c0 |
+ right = tmp;
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
expr = relational_expr_alloc(loc, op, left, right);
|
|
|
f1d1c0 |
ctx->stmt = expr_stmt_alloc(loc, expr);
|
|
|
f1d1c0 |
+ return;
|
|
|
f1d1c0 |
+err_free:
|
|
|
f1d1c0 |
+ expr_free(left);
|
|
|
f1d1c0 |
+ expr_free(right);
|
|
|
f1d1c0 |
}
|
|
|
f1d1c0 |
|
|
|
f1d1c0 |
static void netlink_parse_lookup(struct netlink_parse_ctx *ctx,
|
|
|
f1d1c0 |
--
|
|
|
f1d1c0 |
1.8.3.1
|
|
|
f1d1c0 |
|