58 lines
2.1 KiB
Diff
58 lines
2.1 KiB
Diff
|
From 6a7b38bdb0253cfac68893ff7704f1f9cbfe891a Mon Sep 17 00:00:00 2001
|
||
|
From: Phil Sutter <phil@nwl.cc>
|
||
|
Date: Fri, 30 Sep 2022 17:51:55 +0200
|
||
|
Subject: [PATCH] extensions: among: Fix for use with ebtables-restore
|
||
|
|
||
|
When restoring multiple rules which use among match, new size may be
|
||
|
smaller than the old one which caused invalid writes by the memcpy()
|
||
|
call. Expect this and realloc the match only if it needs to grow. Also
|
||
|
use realloc instead of freeing and allocating from scratch.
|
||
|
|
||
|
Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support")
|
||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||
|
(cherry picked from commit fca04aa7a53252464c289997e71de10189971da6)
|
||
|
---
|
||
|
extensions/libebt_among.c | 14 ++++++--------
|
||
|
1 file changed, 6 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c
|
||
|
index c607a775539d3..1eab201984408 100644
|
||
|
--- a/extensions/libebt_among.c
|
||
|
+++ b/extensions/libebt_among.c
|
||
|
@@ -119,7 +119,6 @@ static int bramong_parse(int c, char **argv, int invert,
|
||
|
struct xt_entry_match **match)
|
||
|
{
|
||
|
struct nft_among_data *data = (struct nft_among_data *)(*match)->data;
|
||
|
- struct xt_entry_match *new_match;
|
||
|
bool have_ip, dst = false;
|
||
|
size_t new_size, cnt;
|
||
|
struct stat stats;
|
||
|
@@ -170,18 +169,17 @@ static int bramong_parse(int c, char **argv, int invert,
|
||
|
new_size *= sizeof(struct nft_among_pair);
|
||
|
new_size += XT_ALIGN(sizeof(struct xt_entry_match)) +
|
||
|
sizeof(struct nft_among_data);
|
||
|
- new_match = xtables_calloc(1, new_size);
|
||
|
- memcpy(new_match, *match, (*match)->u.match_size);
|
||
|
- new_match->u.match_size = new_size;
|
||
|
|
||
|
- data = (struct nft_among_data *)new_match->data;
|
||
|
+ if (new_size > (*match)->u.match_size) {
|
||
|
+ *match = xtables_realloc(*match, new_size);
|
||
|
+ (*match)->u.match_size = new_size;
|
||
|
+ data = (struct nft_among_data *)(*match)->data;
|
||
|
+ }
|
||
|
+
|
||
|
have_ip = nft_among_pairs_have_ip(optarg);
|
||
|
poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip);
|
||
|
parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip);
|
||
|
|
||
|
- free(*match);
|
||
|
- *match = new_match;
|
||
|
-
|
||
|
if (c == AMONG_DST_F || c == AMONG_SRC_F) {
|
||
|
munmap(argv, flen);
|
||
|
close(fd);
|
||
|
--
|
||
|
2.40.0
|
||
|
|