aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/netfilter/arp_tables.c11
-rw-r--r--net/ipv4/netfilter/ip_tables.c26
-rw-r--r--net/ipv6/netfilter/ip6_tables.c26
3 files changed, 50 insertions, 13 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7d7ab94a7a2e..2fdf75da7a70 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -480,6 +480,11 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
480 } 480 }
481 t->u.kernel.target = target; 481 t->u.kernel.target = target;
482 482
483 ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
484 name, e->comefrom, 0, 0);
485 if (ret)
486 goto err;
487
483 if (t->u.kernel.target == &arpt_standard_target) { 488 if (t->u.kernel.target == &arpt_standard_target) {
484 if (!standard_check(t, size)) { 489 if (!standard_check(t, size)) {
485 ret = -EINVAL; 490 ret = -EINVAL;
@@ -490,16 +495,16 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
490 t->u.target_size 495 t->u.target_size
491 - sizeof(*t), 496 - sizeof(*t),
492 e->comefrom)) { 497 e->comefrom)) {
493 module_put(t->u.kernel.target->me);
494 duprintf("arp_tables: check failed for `%s'.\n", 498 duprintf("arp_tables: check failed for `%s'.\n",
495 t->u.kernel.target->name); 499 t->u.kernel.target->name);
496 ret = -EINVAL; 500 ret = -EINVAL;
497 goto out; 501 goto err;
498 } 502 }
499 503
500 (*i)++; 504 (*i)++;
501 return 0; 505 return 0;
502 506err:
507 module_put(t->u.kernel.target->me);
503out: 508out:
504 return ret; 509 return ret;
505} 510}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 16f47c675fef..f884ca223295 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -508,6 +508,7 @@ check_match(struct ipt_entry_match *m,
508 unsigned int *i) 508 unsigned int *i)
509{ 509{
510 struct ipt_match *match; 510 struct ipt_match *match;
511 int ret;
511 512
512 match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, 513 match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
513 m->u.user.revision), 514 m->u.user.revision),
@@ -518,18 +519,27 @@ check_match(struct ipt_entry_match *m,
518 } 519 }
519 m->u.kernel.match = match; 520 m->u.kernel.match = match;
520 521
522 ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
523 name, hookmask, ip->proto,
524 ip->invflags & IPT_INV_PROTO);
525 if (ret)
526 goto err;
527
521 if (m->u.kernel.match->checkentry 528 if (m->u.kernel.match->checkentry
522 && !m->u.kernel.match->checkentry(name, ip, m->data, 529 && !m->u.kernel.match->checkentry(name, ip, m->data,
523 m->u.match_size - sizeof(*m), 530 m->u.match_size - sizeof(*m),
524 hookmask)) { 531 hookmask)) {
525 module_put(m->u.kernel.match->me);
526 duprintf("ip_tables: check failed for `%s'.\n", 532 duprintf("ip_tables: check failed for `%s'.\n",
527 m->u.kernel.match->name); 533 m->u.kernel.match->name);
528 return -EINVAL; 534 ret = -EINVAL;
535 goto err;
529 } 536 }
530 537
531 (*i)++; 538 (*i)++;
532 return 0; 539 return 0;
540err:
541 module_put(m->u.kernel.match->me);
542 return ret;
533} 543}
534 544
535static struct ipt_target ipt_standard_target; 545static struct ipt_target ipt_standard_target;
@@ -565,6 +575,12 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
565 } 575 }
566 t->u.kernel.target = target; 576 t->u.kernel.target = target;
567 577
578 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
579 name, e->comefrom, e->ip.proto,
580 e->ip.invflags & IPT_INV_PROTO);
581 if (ret)
582 goto err;
583
568 if (t->u.kernel.target == &ipt_standard_target) { 584 if (t->u.kernel.target == &ipt_standard_target) {
569 if (!standard_check(t, size)) { 585 if (!standard_check(t, size)) {
570 ret = -EINVAL; 586 ret = -EINVAL;
@@ -575,16 +591,16 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
575 t->u.target_size 591 t->u.target_size
576 - sizeof(*t), 592 - sizeof(*t),
577 e->comefrom)) { 593 e->comefrom)) {
578 module_put(t->u.kernel.target->me);
579 duprintf("ip_tables: check failed for `%s'.\n", 594 duprintf("ip_tables: check failed for `%s'.\n",
580 t->u.kernel.target->name); 595 t->u.kernel.target->name);
581 ret = -EINVAL; 596 ret = -EINVAL;
582 goto cleanup_matches; 597 goto err;
583 } 598 }
584 599
585 (*i)++; 600 (*i)++;
586 return 0; 601 return 0;
587 602 err:
603 module_put(t->u.kernel.target->me);
588 cleanup_matches: 604 cleanup_matches:
589 IPT_MATCH_ITERATE(e, cleanup_match, &j); 605 IPT_MATCH_ITERATE(e, cleanup_match, &j);
590 return ret; 606 return ret;
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;