[iptables PATCH 17/23] arptables: Fix memleaks in target handling

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

 



First of all, xtables_find_target() may return an already loaded target,
so avoid allocating per-target memory and options merging since that has
been done already.

In contrast to the same fix for ebtables, this case has to be detected
by checking whether field 't' is non-zero. Looking at option_offset does
not work since 'standard' target does not contain extra options, which
means option_offset is not changed for it.

Second of all, if option merging took place, the old option buffer has
to be freed (if it was a dynamically allocated). For this to work, the
bits which reset global 'opts' variable have to be dropped. In fact,
they are not necessary at all.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 iptables/xtables-arp.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index fa0119bfd496b..1132478878127 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -150,7 +150,6 @@ static struct option original_opts[] = {
 int RUNTIME_NF_ARP_NUMHOOKS = 3;
 
 static struct option *opts = original_opts;
-static unsigned int global_option_offset;
 
 extern void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
 struct xtables_globals arptables_globals = {
@@ -826,6 +825,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
 static struct xtables_target *command_jump(struct arpt_entry *fw,
 					   const char *jumpto)
 {
+	struct option *old_opts = opts;
 	struct xtables_target *target;
 	size_t size;
 
@@ -835,6 +835,9 @@ static struct xtables_target *command_jump(struct arpt_entry *fw,
 	if (!target)
 		return NULL;
 
+	if (target->t)
+		return target;
+
 	size = XT_ALIGN(sizeof(struct xt_entry_target))
 		+ target->size;
 
@@ -855,6 +858,9 @@ static struct xtables_target *command_jump(struct arpt_entry *fw,
 					     opts, target->extra_opts,
 					     &target->option_offset);
 
+	if (opts != old_opts && old_opts != original_opts)
+		free(old_opts);
+
 	return target;
 }
 
@@ -975,11 +981,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
 	int ret = 1;
 	struct xtables_target *t;
 
-	opts = original_opts;
-	global_option_offset = 0;
-
-	xtables_globals.orig_opts = original_opts;
-
 	/* re-set optind to 0 in case do_command gets called
 	 * a second time */
 	optind = 0;
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux