[iptables PATCH 04/10] ebtables-translate: Fix segfault while parsing extension options

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

 



Previous review of match/target lookup did not consider
xtables-eb-translate.c which contains the same code. Fix parsing of
target/match arguments there as well by introducing
ebt_command_default() which consolidates the previously duplicated code.

One notable quirk in comparison to the similar xtables code: Since
ebtables allows for negations in ugly places (e.g. '--arp-opcode ! 1'),
ebt_check_inverse2() has to be called first.

Fixes: aa7fb04fcf72c ("ebtables: Review match/target lookup")
Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 iptables/nft-bridge.h           |  1 +
 iptables/xtables-eb-translate.c | 33 +++----------
 iptables/xtables-eb.c           | 86 +++++++++++++++------------------
 3 files changed, 47 insertions(+), 73 deletions(-)

diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index 8dcb151f9e36e..601476ddb84ed 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -120,5 +120,6 @@ void ebt_add_match(struct xtables_match *m,
 			  struct iptables_command_state *cs);
 void ebt_add_watcher(struct xtables_target *watcher,
                      struct iptables_command_state *cs);
+int ebt_command_default(struct iptables_command_state *cs);
 
 #endif
diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c
index 1e66bf71a5ede..145653d5a8f2c 100644
--- a/iptables/xtables-eb-translate.c
+++ b/iptables/xtables-eb-translate.c
@@ -286,7 +286,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char
 	int rule_nr_end = 0;
 	int ret = 0;
 	unsigned int flags = 0;
-	struct xtables_target *t, *w;
+	struct xtables_target *t;
 	struct xtables_match *m;
 	struct iptables_command_state cs = {
 		.argv		= argv,
@@ -620,34 +620,13 @@ print_zero:
 			optind--;
 			continue;
 		default:
-			/* Is it a target option? */
-			if (cs.target != NULL && cs.target->parse != NULL) {
-				int opt_offset = cs.target->option_offset;
-				if (cs.target->parse(c - opt_offset,
-						     argv, ebt_invert,
-						     &cs.target->tflags,
-						     NULL, &cs.target->t))
-					goto check_extension;
-			}
+			ebt_check_inverse2(optarg, argc, argv);
 
-			/* Is it a match_option? */
-			for (m = xtables_matches; m; m = m->next) {
-				if (m->parse(c - m->option_offset, argv, ebt_check_inverse2(optarg, argc, argv), &m->mflags, NULL, &m->m)) {
-					ebt_add_match(m, &cs);
-					goto check_extension;
-				}
-			}
+			if (ebt_command_default(&cs))
+				xtables_error(PARAMETER_PROBLEM,
+					      "Unknown argument: '%s'",
+					      argv[optind - 1]);
 
-			/* Is it a watcher option? */
-			for (w = xtables_targets; w; w = w->next) {
-				if (w->parse(c - w->option_offset, argv,
-					     ebt_invert, &w->tflags,
-					     NULL, &w->t)) {
-					ebt_add_watcher(w, &cs);
-					goto check_extension;
-				}
-			}
-check_extension:
 			if (command != 'A' && command != 'I' &&
 			    command != 'D')
 				xtables_error(PARAMETER_PROBLEM,
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 68f12500e524d..c4d458d420184 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -720,6 +720,40 @@ void ebt_add_watcher(struct xtables_target *watcher,
 	*matchp = newnode;
 }
 
+int ebt_command_default(struct iptables_command_state *cs)
+{
+	struct xtables_target *t = cs->target;
+	struct xtables_match *m;
+
+	/* Is it a target option? */
+	if (t && t->parse) {
+		if (t->parse(cs->c - t->option_offset, cs->argv,
+			     ebt_invert, &t->tflags, NULL, &t->t))
+			return 0;
+	}
+
+	/* Is it a match_option? */
+	for (m = xtables_matches; m; m = m->next) {
+		if (m->parse &&
+		    m->parse(cs->c - m->option_offset, cs->argv,
+			     ebt_invert, &m->mflags, NULL, &m->m)) {
+			ebt_add_match(m, cs);
+			return 0;
+		}
+	}
+
+	/* Is it a watcher option? */
+	for (t = xtables_targets; t; t = t->next) {
+		if (t->parse &&
+		    t->parse(cs->c - t->option_offset, cs->argv,
+			     ebt_invert, &t->tflags, NULL, &t->t)) {
+			ebt_add_watcher(t, cs);
+			return 0;
+		}
+	}
+	return 1;
+}
+
 int nft_init_eb(struct nft_handle *h, const char *pname)
 {
 	ebtables_globals.program_name = pname;
@@ -765,7 +799,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
 	int rule_nr_end = 0;
 	int ret = 0;
 	unsigned int flags = 0;
-	struct xtables_target *t, *w;
+	struct xtables_target *t;
 	struct xtables_match *m;
 	struct iptables_command_state cs = {
 		.argv = argv,
@@ -1187,53 +1221,13 @@ print_zero:
 			optind--;
 			continue;
 		default:
-			/* Is it a target option? */
-			if (cs.target != NULL && cs.target->parse != NULL) {
-				int opt_offset = cs.target->option_offset;
-				if (cs.target->parse(c - opt_offset,
-						     argv, ebt_invert,
-						     &cs.target->tflags,
-						     NULL, &cs.target->t))
-					goto check_extension;
-			}
+			ebt_check_inverse2(optarg, argc, argv);
 
-			/* Is it a match_option? */
-			for (m = xtables_matches; m; m = m->next) {
-				if (m->parse &&
-				    m->parse(c - m->option_offset, argv,
-					     ebt_check_inverse2(optarg, argc, argv),
-					     &m->mflags, NULL, &m->m)) {
-					ebt_add_match(m, &cs);
-					goto check_extension;
-				}
-			}
+			if (ebt_command_default(&cs))
+				xtables_error(PARAMETER_PROBLEM,
+					      "Unknown argument: '%s'",
+					      argv[optind - 1]);
 
-			/* Is it a watcher option? */
-			for (w = xtables_targets; w; w = w->next) {
-				if (w->parse &&
-				    w->parse(c - w->option_offset, argv,
-					     ebt_invert, &w->tflags,
-					     NULL, &w->t)) {
-					ebt_add_watcher(w, &cs);
-					goto check_extension;
-				}
-			}
-			/*
-			if (w == NULL && c == '?')
-				ebt_print_error2("Unknown argument: '%s'", argv[optind - 1], (char)optopt, (char)c);
-			else if (w == NULL) {
-				if (!strcmp(t->name, "standard"))
-					ebt_print_error2("Unknown argument: don't forget the -t option");
-				else
-					ebt_print_error2("Target-specific option does not correspond with specified target");
-			}
-			if (ebt_errormsg[0] != '\0')
-				return -1;
-			if (w->used == 0) {
-				ebt_add_watcher(new_entry, w);
-				w->used = 1;
-			}*/
-check_extension:
 			if (command != 'A' && command != 'I' &&
 			    command != 'D' && command != 'C')
 				xtables_error(PARAMETER_PROBLEM,
-- 
2.18.0




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

  Powered by Linux