diff options
author | Arturo Borrero <arturo.borrero.glez@gmail.com> | 2015-04-08 19:42:19 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-04-09 19:03:07 +0200 |
commit | 06d14d702e481f29d5fdc33afab4347e6efb678d (patch) | |
tree | d2ff0fd852958de0041f60d77599f6e8e1b1eb24 /libxtables/xtables.c | |
parent | 86a65af62b6b986aa2ae3cbf3c655ea8225b027a (diff) |
libxtables: find extensions based on family too
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>
Diffstat (limited to 'libxtables/xtables.c')
-rw-r--r-- | libxtables/xtables.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 9df12ce5..5357d12c 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -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; } |