|
|
621646 |
From 66b9f92ef41de90fc2b0359247c36bc6d128233d Mon Sep 17 00:00:00 2001
|
|
|
621646 |
From: Phil Sutter <phil@nwl.cc>
|
|
|
621646 |
Date: Fri, 28 Feb 2020 20:32:13 +0100
|
|
|
621646 |
Subject: [PATCH] nft: cache: Fix nft_release_cache() under stress
|
|
|
621646 |
|
|
|
621646 |
iptables-nft-restore calls nft_action(h, NFT_COMPAT_COMMIT) for each
|
|
|
621646 |
COMMIT line in input. When restoring a dump containing multiple large
|
|
|
621646 |
tables, chances are nft_rebuild_cache() has to run multiple times.
|
|
|
621646 |
|
|
|
621646 |
If the above happens, consecutive table contents are added to __cache[1]
|
|
|
621646 |
which nft_rebuild_cache() then frees, so next commit attempt accesses
|
|
|
621646 |
invalid memory.
|
|
|
621646 |
|
|
|
621646 |
Fix this by making nft_release_cache() (called after each successful
|
|
|
621646 |
commit) return things into pre-rebuild state again, but keeping the
|
|
|
621646 |
fresh cache copy.
|
|
|
621646 |
|
|
|
621646 |
Fixes: f6ad231d698c7 ("nft: keep original cache in case of ERESTART")
|
|
|
621646 |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
621646 |
(cherry picked from commit c550c81fd373e5753103d20f7902171f0fa79807)
|
|
|
621646 |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
621646 |
---
|
|
|
621646 |
iptables/nft-cache.c | 10 ++++++++--
|
|
|
621646 |
1 file changed, 8 insertions(+), 2 deletions(-)
|
|
|
621646 |
|
|
|
621646 |
diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
|
|
|
621646 |
index 7345a27e2894b..6f21f2283e0fb 100644
|
|
|
621646 |
--- a/iptables/nft-cache.c
|
|
|
621646 |
+++ b/iptables/nft-cache.c
|
|
|
621646 |
@@ -647,8 +647,14 @@ void nft_rebuild_cache(struct nft_handle *h)
|
|
|
621646 |
|
|
|
621646 |
void nft_release_cache(struct nft_handle *h)
|
|
|
621646 |
{
|
|
|
621646 |
- if (h->cache_index)
|
|
|
621646 |
- flush_cache(h, &h->__cache[0], NULL);
|
|
|
621646 |
+ if (!h->cache_index)
|
|
|
621646 |
+ return;
|
|
|
621646 |
+
|
|
|
621646 |
+ flush_cache(h, &h->__cache[0], NULL);
|
|
|
621646 |
+ memcpy(&h->__cache[0], &h->__cache[1], sizeof(h->__cache[0]));
|
|
|
621646 |
+ memset(&h->__cache[1], 0, sizeof(h->__cache[1]));
|
|
|
621646 |
+ h->cache_index = 0;
|
|
|
621646 |
+ h->cache = &h->__cache[0];
|
|
|
621646 |
}
|
|
|
621646 |
|
|
|
621646 |
struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h)
|
|
|
621646 |
--
|
|
|
621646 |
2.25.1
|
|
|
621646 |
|