]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ebtables-translate: Fix segfault while parsing extension options
authorPhil Sutter <phil@nwl.cc>
Thu, 23 Aug 2018 15:43:23 +0000 (17:43 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 Aug 2018 08:05:51 +0000 (10:05 +0200)
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@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft-bridge.h
iptables/xtables-eb-translate.c
iptables/xtables-eb.c

index 8dcb151f9e36e35a523ab460ad01de0e9c856791..601476ddb84ed325d9c80bebfc3b93ac5ff63d3a 100644 (file)
@@ -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
index 1e66bf71a5edea0a00d9b16501e85a18ba92fcca..145653d5a8f2cef9847023080d8ba39fa13f11bd 100644 (file)
@@ -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,
index 68f12500e524d79ea0fd620a7f4b5a1c54dee831..c4d458d42018427530e590f2634e4ae5ac061894 100644 (file)
@@ -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,