diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2009-07-09 16:54:53 -0400 |
---|---|---|
committer | Jan Engelhardt <jengelh@medozas.de> | 2009-08-10 07:35:29 -0400 |
commit | 90e7d4ab5c8b0c4c2e00e4893977f6aeec0f18f1 (patch) | |
tree | 81951e3cb17713cd0cedfec9d4d3823d3fe264f5 /net | |
parent | a7d51738e757c1ab94595e7d05594c61f0fb32ce (diff) |
netfilter: xtables: check for unconditionality of policies
This adds a check that iptables's original author Rusty set forth in
a FIXME comment.
Underflows in iptables are better known as chain policies, and are
required to be unconditional or there would be a stochastical chance
for the policy rule to be skipped if it does not match. If that were
to happen, rule execution would continue in an unexpected spurious
fashion.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 12 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 11 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 12 |
3 files changed, 21 insertions, 14 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index d91f0834d572..064082dffafb 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * Copyright (C) 2002 David S. Miller (davem@redhat.com) | 8 | * Copyright (C) 2002 David S. Miller (davem@redhat.com) |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/skbuff.h> | 13 | #include <linux/skbuff.h> |
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
@@ -563,13 +563,15 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
563 | continue; | 563 | continue; |
564 | if ((unsigned char *)e - base == hook_entries[h]) | 564 | if ((unsigned char *)e - base == hook_entries[h]) |
565 | newinfo->hook_entry[h] = hook_entries[h]; | 565 | newinfo->hook_entry[h] = hook_entries[h]; |
566 | if ((unsigned char *)e - base == underflows[h]) | 566 | if ((unsigned char *)e - base == underflows[h]) { |
567 | if (!unconditional(&e->arp)) { | ||
568 | pr_err("Underflows must be unconditional\n"); | ||
569 | return -EINVAL; | ||
570 | } | ||
567 | newinfo->underflow[h] = underflows[h]; | 571 | newinfo->underflow[h] = underflows[h]; |
572 | } | ||
568 | } | 573 | } |
569 | 574 | ||
570 | /* FIXME: underflows must be unconditional, standard verdicts | ||
571 | < 0 (not ARPT_RETURN). --RR */ | ||
572 | |||
573 | /* Clear counters and comefrom */ | 575 | /* Clear counters and comefrom */ |
574 | e->counters = ((struct xt_counters) { 0, 0 }); | 576 | e->counters = ((struct xt_counters) { 0, 0 }); |
575 | e->comefrom = 0; | 577 | e->comefrom = 0; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 6e7b7e8b80b1..6e546d573d9c 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
11 | #include <linux/cache.h> | 12 | #include <linux/cache.h> |
12 | #include <linux/capability.h> | 13 | #include <linux/capability.h> |
13 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
@@ -738,13 +739,15 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
738 | continue; | 739 | continue; |
739 | if ((unsigned char *)e - base == hook_entries[h]) | 740 | if ((unsigned char *)e - base == hook_entries[h]) |
740 | newinfo->hook_entry[h] = hook_entries[h]; | 741 | newinfo->hook_entry[h] = hook_entries[h]; |
741 | if ((unsigned char *)e - base == underflows[h]) | 742 | if ((unsigned char *)e - base == underflows[h]) { |
743 | if (!unconditional(&e->ip)) { | ||
744 | pr_err("Underflows must be unconditional\n"); | ||
745 | return -EINVAL; | ||
746 | } | ||
742 | newinfo->underflow[h] = underflows[h]; | 747 | newinfo->underflow[h] = underflows[h]; |
748 | } | ||
743 | } | 749 | } |
744 | 750 | ||
745 | /* FIXME: underflows must be unconditional, standard verdicts | ||
746 | < 0 (not IPT_RETURN). --RR */ | ||
747 | |||
748 | /* Clear counters and comefrom */ | 751 | /* Clear counters and comefrom */ |
749 | e->counters = ((struct xt_counters) { 0, 0 }); | 752 | e->counters = ((struct xt_counters) { 0, 0 }); |
750 | e->comefrom = 0; | 753 | e->comefrom = 0; |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 8e4921a937ff..b0599b98d1b6 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
14 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
@@ -771,13 +771,15 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
771 | continue; | 771 | continue; |
772 | if ((unsigned char *)e - base == hook_entries[h]) | 772 | if ((unsigned char *)e - base == hook_entries[h]) |
773 | newinfo->hook_entry[h] = hook_entries[h]; | 773 | newinfo->hook_entry[h] = hook_entries[h]; |
774 | if ((unsigned char *)e - base == underflows[h]) | 774 | if ((unsigned char *)e - base == underflows[h]) { |
775 | if (!unconditional(&e->ipv6)) { | ||
776 | pr_err("Underflows must be unconditional\n"); | ||
777 | return -EINVAL; | ||
778 | } | ||
775 | newinfo->underflow[h] = underflows[h]; | 779 | newinfo->underflow[h] = underflows[h]; |
780 | } | ||
776 | } | 781 | } |
777 | 782 | ||
778 | /* FIXME: underflows must be unconditional, standard verdicts | ||
779 | < 0 (not IP6T_RETURN). --RR */ | ||
780 | |||
781 | /* Clear counters and comefrom */ | 783 | /* Clear counters and comefrom */ |
782 | e->counters = ((struct xt_counters) { 0, 0 }); | 784 | e->counters = ((struct xt_counters) { 0, 0 }); |
783 | e->comefrom = 0; | 785 | e->comefrom = 0; |