[iptables PATCH 06/23] xtables: Fix ebtables-restore

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

 



This fixes a bunch of issues found when actually testing my code:

* Although add_param_to_argv() takes care of the trailing newline
  character, it has to be removed for lines defining tables and chains.
* Table flushing must be done in a separate transaction, otherwise the
  cache still contains old entries and automatic insertion of built-in
  chains does not happen.
* Call nft_table_new() for each table definition to trigger creation of
  built-in chains. Otherwise the relevant batch jobs are later inserted
  after those created by chain definitions, effectively undoing any
  policy changes.
* Fix off-by-one when assigning to variable pointing at chain name in
  chain definition.
* Skip chain policy setting for non-built-in chains.
* Make sure free_argv() is called after each call to do_commandeb().
* Call nft_fini() before returning to caller.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 iptables/xtables-restore.c | 39 ++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 5c0ae98e8821a..ead61842bc360 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -645,30 +645,38 @@ int xtables_eb_restore_main(int argc, char *argv[])
 		if (buffer[0] == '#' || buffer[0] == '\n')
 			continue;
 		if (buffer[0] == '*') {
+			*strchr(buffer, '\n') = '\0';
 			table = ebt_parse_table_name(buffer + 1);
-			if (flush)
+			if (flush) {
 				nft_table_flush(&h, table);
+				nft_commit(&h);
+			}
+			nft_table_new(&h, table);
 			continue;
 		} else if (!table) {
 			xtables_error(PARAMETER_PROBLEM, "no table specified");
 		}
 		if (buffer[0] == ':') {
-			char *ch, *chain = buffer;
+			char *ch, *chain = buffer + 1;
 			const char *policy;
 
 			if (!(ch = strchr(buffer, ' ')))
 				xtables_error(PARAMETER_PROBLEM, "no policy specified");
 			*ch = '\0';
+			*strchr(ch + 1, '\n') = '\0';
 			policy = ebt_parse_policy_name(ch + 1);
 
 			/* No need to check chain name for consistency, since
 			 * we're supposed to be reading an automatically generated
 			 * file. */
-			if (ebt_get_current_chain(chain) < 0)
+			if (ebt_get_current_chain(chain) < 0) {
 				nft_chain_user_add(&h, chain, table);
-			ret = nft_chain_set(&h, table, chain, policy, NULL);
-			if (ret < 0)
-				xtables_error(PARAMETER_PROBLEM, "Wrong policy");
+			} else {
+				ret = nft_chain_set(&h, table, chain, policy, NULL);
+				if (!ret)
+					xtables_error(PARAMETER_PROBLEM,
+						      "Wrong policy '%s' of chain %s in table %s", policy, chain, table);
+			}
 			continue;
 		}
 
@@ -685,13 +693,20 @@ int xtables_eb_restore_main(int argc, char *argv[])
 			DEBUGP("argv[%u]: %s\n", i, newargv[i]);
 
 		optind = 0; /* Setting optind = 1 causes serious annoyances */
-		if (!do_commandeb(&h, newargc, newargv, &newargv[2]))
-			return 1;
+		ret = do_commandeb(&h, newargc, newargv, &newargv[2]);
+
+		free_argv();
+
+		if (!ret)
+			break;
 	}
 
-	if (!nft_commit(&h)) {
+	if (ret)
+		ret = nft_commit(&h);
+
+	nft_fini(&h);
+
+	if (!ret)
 		fprintf(stderr, "%s\n", nft_strerror(errno));
-		return 1;
-	}
-	return 0;
+	return !ret;
 }
-- 
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