summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2015-04-08 19:42:19 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-04-09 19:03:07 +0200
commit06d14d702e481f29d5fdc33afab4347e6efb678d (patch)
treed2ff0fd852958de0041f60d77599f6e8e1b1eb24
parent86a65af62b6b986aa2ae3cbf3c655ea8225b027a (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>
-rw-r--r--libxtables/xtables.c21
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;
}