]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: find extensions based on family too
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Wed, 8 Apr 2015 17:42:19 +0000 (19:42 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 9 Apr 2015 17:03:07 +0000 (19:03 +0200)
When using libxtables with an external program (nft) which switches family
contexts (using xtables_set_nfproto()), the xtables_find_{match,target}
functions need to compare the family too.

We want to avoid this situation:

 1) user first sets afinfo to IPv6
 2) xtables_find_target() finds & load ip6t_REJECT and uses it
 3) afinfo change to IPv4
 4) user then tries to use ipt_REJECT
 5) xtables_find_target() finds ip6t_REJECT instead (same target name)
 6) using ip6t_REJECT as ipt_REJECT can cause a lot of troubles

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
libxtables/xtables.c

index 9df12ce5cd1fecf51ddcc43419202658644d5e21..5357d12c748114806bbbe3c5ff6077dcb4e6d283 100644 (file)
@@ -603,6 +603,16 @@ static void *load_extension(const char *search_path, const char *af_prefix,
 }
 #endif
 
+static bool extension_cmp(const char *name1, const char *name2, uint32_t family)
+{
+       if (strcmp(name1, name2) == 0 &&
+           (family == afinfo->family ||
+            family == NFPROTO_UNSPEC))
+               return true;
+
+       return false;
+}
+
 struct xtables_match *
 xtables_find_match(const char *name, enum xtables_tryload tryload,
                   struct xtables_rule_match **matches)
@@ -625,7 +635,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
 
        /* Trigger delayed initialization */
        for (dptr = &xtables_pending_matches; *dptr; ) {
-               if (strcmp(name, (*dptr)->name) == 0) {
+               if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
                        ptr = *dptr;
                        *dptr = (*dptr)->next;
                        ptr->next = NULL;
@@ -636,7 +646,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
        }
 
        for (ptr = xtables_matches; ptr; ptr = ptr->next) {
-               if (strcmp(name, ptr->name) == 0) {
+               if (extension_cmp(name, ptr->name, ptr->family)) {
                        struct xtables_match *clone;
 
                        /* First match of this type: */
@@ -686,7 +696,8 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
                newentry = xtables_malloc(sizeof(struct xtables_rule_match));
 
                for (i = matches; *i; i = &(*i)->next) {
-                       if (strcmp(name, (*i)->match->name) == 0)
+                       if (extension_cmp(name, (*i)->match->name,
+                                         (*i)->match->family))
                                (*i)->completed = true;
                }
                newentry->match = ptr;
@@ -714,7 +725,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
 
        /* Trigger delayed initialization */
        for (dptr = &xtables_pending_targets; *dptr; ) {
-               if (strcmp(name, (*dptr)->name) == 0) {
+               if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
                        ptr = *dptr;
                        *dptr = (*dptr)->next;
                        ptr->next = NULL;
@@ -725,7 +736,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
        }
 
        for (ptr = xtables_targets; ptr; ptr = ptr->next) {
-               if (strcmp(name, ptr->name) == 0)
+               if (extension_cmp(name, ptr->name, ptr->family))
                        break;
        }