aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2009-07-09 16:54:53 -0400
committerJan Engelhardt <jengelh@medozas.de>2009-08-10 07:35:29 -0400
commit90e7d4ab5c8b0c4c2e00e4893977f6aeec0f18f1 (patch)
tree81951e3cb17713cd0cedfec9d4d3823d3fe264f5 /net
parenta7d51738e757c1ab94595e7d05594c61f0fb32ce (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.c12
-rw-r--r--net/ipv4/netfilter/ip_tables.c11
-rw-r--r--net/ipv6/netfilter/ip6_tables.c12
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;