aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6_tables.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 74ff56c322f4..1cd70683f2e2 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -575,6 +575,7 @@ check_match(struct ip6t_entry_match *m,
575 unsigned int *i) 575 unsigned int *i)
576{ 576{
577 struct ip6t_match *match; 577 struct ip6t_match *match;
578 int ret;
578 579
579 match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, 580 match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
580 m->u.user.revision), 581 m->u.user.revision),
@@ -585,18 +586,27 @@ check_match(struct ip6t_entry_match *m,
585 } 586 }
586 m->u.kernel.match = match; 587 m->u.kernel.match = match;
587 588
589 ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
590 name, hookmask, ipv6->proto,
591 ipv6->invflags & IP6T_INV_PROTO);
592 if (ret)
593 goto err;
594
588 if (m->u.kernel.match->checkentry 595 if (m->u.kernel.match->checkentry
589 && !m->u.kernel.match->checkentry(name, ipv6, m->data, 596 && !m->u.kernel.match->checkentry(name, ipv6, m->data,
590 m->u.match_size - sizeof(*m), 597 m->u.match_size - sizeof(*m),
591 hookmask)) { 598 hookmask)) {
592 module_put(m->u.kernel.match->me);
593 duprintf("ip_tables: check failed for `%s'.\n", 599 duprintf("ip_tables: check failed for `%s'.\n",
594 m->u.kernel.match->name); 600 m->u.kernel.match->name);
595 return -EINVAL; 601 ret = -EINVAL;
602 goto err;
596 } 603 }
597 604
598 (*i)++; 605 (*i)++;
599 return 0; 606 return 0;
607err:
608 module_put(m->u.kernel.match->me);
609 return ret;
600} 610}
601 611
602static struct ip6t_target ip6t_standard_target; 612static struct ip6t_target ip6t_standard_target;
@@ -632,6 +642,12 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
632 } 642 }
633 t->u.kernel.target = target; 643 t->u.kernel.target = target;
634 644
645 ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
646 name, e->comefrom, e->ipv6.proto,
647 e->ipv6.invflags & IP6T_INV_PROTO);
648 if (ret)
649 goto err;
650
635 if (t->u.kernel.target == &ip6t_standard_target) { 651 if (t->u.kernel.target == &ip6t_standard_target) {
636 if (!standard_check(t, size)) { 652 if (!standard_check(t, size)) {
637 ret = -EINVAL; 653 ret = -EINVAL;
@@ -642,16 +658,16 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
642 t->u.target_size 658 t->u.target_size
643 - sizeof(*t), 659 - sizeof(*t),
644 e->comefrom)) { 660 e->comefrom)) {
645 module_put(t->u.kernel.target->me);
646 duprintf("ip_tables: check failed for `%s'.\n", 661 duprintf("ip_tables: check failed for `%s'.\n",
647 t->u.kernel.target->name); 662 t->u.kernel.target->name);
648 ret = -EINVAL; 663 ret = -EINVAL;
649 goto cleanup_matches; 664 goto err;
650 } 665 }
651 666
652 (*i)++; 667 (*i)++;
653 return 0; 668 return 0;
654 669 err:
670 module_put(t->u.kernel.target->me);
655 cleanup_matches: 671 cleanup_matches:
656 IP6T_MATCH_ITERATE(e, cleanup_match, &j); 672 IP6T_MATCH_ITERATE(e, cleanup_match, &j);
657 return ret; 673 return ret;