[iptables PATCH 03/15] nft: Avoid use-after-free when rebuilding cache

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



By the time nft_action() decides to rebuild the cache, nft_cmd structs
have been freed already and therefore table and chain names in
nft_cache_req point to invalid memory.

Fix this by duplicating the strings and freeing them when releasing the
cache.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 iptables/nft-cache.c | 14 ++++++++++----
 iptables/nft.h       |  4 ++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c
index 83af9a2f689e1..84ea97d3e54a6 100644
--- a/iptables/nft-cache.c
+++ b/iptables/nft-cache.c
@@ -39,7 +39,7 @@ static void cache_chain_list_insert(struct list_head *list, const char *name)
 	}
 
 	new = xtables_malloc(sizeof(*new));
-	new->name = name;
+	new->name = strdup(name);
 	list_add_tail(&new->head, pos ? &pos->head : list);
 }
 
@@ -54,7 +54,10 @@ void nft_cache_level_set(struct nft_handle *h, int level,
 	if (!cmd || !cmd->table || req->all_chains)
 		return;
 
-	req->table = cmd->table;
+	if (!req->table)
+		req->table = strdup(cmd->table);
+	else
+		assert(!strcmp(req->table, cmd->table));
 
 	if (!cmd->chain) {
 		req->all_chains = true;
@@ -663,11 +666,14 @@ void nft_release_cache(struct nft_handle *h)
 
 	if (req->level != NFT_CL_FAKE)
 		req->level = NFT_CL_TABLES;
-	req->table = NULL;
-
+	if (req->table) {
+		free(req->table);
+		req->table = NULL;
+	}
 	req->all_chains = false;
 	list_for_each_entry_safe(cc, cc_tmp, &req->chain_list, head) {
 		list_del(&cc->head);
+		free(cc->name);
 		free(cc);
 	}
 }
diff --git a/iptables/nft.h b/iptables/nft.h
index 045393da7c179..aeacc608fcb9f 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -73,12 +73,12 @@ enum obj_update_type {
 
 struct cache_chain {
 	struct list_head head;
-	const char *name;
+	char *name;
 };
 
 struct nft_cache_req {
 	enum nft_cache_level	level;
-	const char		*table;
+	char			*table;
 	bool			all_chains;
 	struct list_head	chain_list;
 };
-- 
2.25.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux