kernel: add missing checks in the netfilter optimization patch which broke some rules...
authorFelix Fietkau <nbd@openwrt.org>
Sat, 6 Aug 2011 12:39:31 +0000 (12:39 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 6 Aug 2011 12:39:31 +0000 (12:39 +0000)
SVN-Revision: 27923

target/linux/generic/patches-2.6.39/610-netfilter_match_bypass_default_checks.patch
target/linux/generic/patches-2.6.39/611-netfilter_match_bypass_default_table.patch
target/linux/generic/patches-3.0/610-netfilter_match_bypass_default_checks.patch
target/linux/generic/patches-3.0/611-netfilter_match_bypass_default_table.patch

index ac0fd151cdc16119cfd7c336357fcc2bdbfec45b..98c28c743353f65ca7295929ccf1f5ddc8bf44c9 100644 (file)
@@ -20,7 +20,7 @@
        if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
                  IPT_INV_SRCIP) ||
            FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
-@@ -143,6 +146,26 @@ ip_packet_match(const struct iphdr *ip,
+@@ -143,6 +146,29 @@ ip_packet_match(const struct iphdr *ip,
        return true;
  }
  
@@ -38,6 +38,9 @@
 +      if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
 +              return;
 +
++      if (ip->smsk.s_addr || ip->dmsk.s_addr)
++              return;
++
 +      if (ip->proto)
 +              return;
 +
@@ -47,7 +50,7 @@
  static bool
  ip_checkentry(const struct ipt_ip *ip)
  {
-@@ -566,7 +589,7 @@ static void cleanup_match(struct xt_entr
+@@ -566,7 +592,7 @@ static void cleanup_match(struct xt_entr
  }
  
  static int
@@ -56,7 +59,7 @@
  {
        const struct xt_entry_target *t;
  
-@@ -575,6 +598,8 @@ check_entry(const struct ipt_entry *e, c
+@@ -575,6 +601,8 @@ check_entry(const struct ipt_entry *e, c
                return -EINVAL;
        }
  
@@ -65,7 +68,7 @@
        if (e->target_offset + sizeof(struct xt_entry_target) >
            e->next_offset)
                return -EINVAL;
-@@ -936,6 +961,7 @@ copy_entries_to_user(unsigned int total_
+@@ -936,6 +964,7 @@ copy_entries_to_user(unsigned int total_
        const struct xt_table_info *private = table->private;
        int ret = 0;
        const void *loc_cpu_entry;
@@ -73,7 +76,7 @@
  
        counters = alloc_counters(table);
        if (IS_ERR(counters))
-@@ -967,6 +993,14 @@ copy_entries_to_user(unsigned int total_
+@@ -967,6 +996,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
  
index f2004a6b12e8e4fd345b2b42c9206491113c3b70..0ea58c95d9e04bbd7e0010a8c6b09f39d07d57f3 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/ipv4/netfilter/ip_tables.c
 +++ b/net/ipv4/netfilter/ip_tables.c
-@@ -316,6 +316,33 @@ struct ipt_entry *ipt_next_entry(const s
+@@ -319,6 +319,33 @@ struct ipt_entry *ipt_next_entry(const s
        return (void *)entry + entry->next_offset;
  }
  
@@ -34,7 +34,7 @@
  /* Returns one of the generic firewall policies, like NF_ACCEPT. */
  unsigned int
  ipt_do_table(struct sk_buff *skb,
-@@ -339,6 +366,23 @@ ipt_do_table(struct sk_buff *skb,
+@@ -342,6 +369,23 @@ ipt_do_table(struct sk_buff *skb,
        ip = ip_hdr(skb);
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
@@ -58,7 +58,7 @@
        /* We handle fragments by dealing with the first fragment as
         * if it was a normal packet.  All other fragments are treated
         * normally, except that they will NEVER match rules that ask
-@@ -353,17 +397,6 @@ ipt_do_table(struct sk_buff *skb,
+@@ -356,17 +400,6 @@ ipt_do_table(struct sk_buff *skb,
        acpar.family  = NFPROTO_IPV4;
        acpar.hooknum = hook;
  
index 4760c8ad85e5c229f6d2df156461de7d9ddf60a2..b65e00ff82ac9851ec0b145a91cd97009d53b95d 100644 (file)
@@ -20,7 +20,7 @@
        if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
                  IPT_INV_SRCIP) ||
            FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
-@@ -134,6 +137,26 @@ ip_packet_match(const struct iphdr *ip,
+@@ -134,6 +137,29 @@ ip_packet_match(const struct iphdr *ip,
        return true;
  }
  
@@ -38,6 +38,9 @@
 +      if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
 +              return;
 +
++      if (ip->smsk.s_addr || ip->dmsk.s_addr)
++              return;
++
 +      if (ip->proto)
 +              return;
 +
@@ -47,7 +50,7 @@
  static bool
  ip_checkentry(const struct ipt_ip *ip)
  {
-@@ -561,7 +584,7 @@ static void cleanup_match(struct xt_entr
+@@ -561,7 +587,7 @@ static void cleanup_match(struct xt_entr
  }
  
  static int
@@ -56,7 +59,7 @@
  {
        const struct xt_entry_target *t;
  
-@@ -570,6 +593,8 @@ check_entry(const struct ipt_entry *e, c
+@@ -570,6 +596,8 @@ check_entry(const struct ipt_entry *e, c
                return -EINVAL;
        }
  
@@ -65,7 +68,7 @@
        if (e->target_offset + sizeof(struct xt_entry_target) >
            e->next_offset)
                return -EINVAL;
-@@ -931,6 +956,7 @@ copy_entries_to_user(unsigned int total_
+@@ -931,6 +959,7 @@ copy_entries_to_user(unsigned int total_
        const struct xt_table_info *private = table->private;
        int ret = 0;
        const void *loc_cpu_entry;
  
        counters = alloc_counters(table);
        if (IS_ERR(counters))
-@@ -961,6 +987,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -962,6 +991,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & IPT_F_MASK;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
@@ -85,6 +87,7 @@
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {
index 113f1401232ff02ae5f386c8a0193b2abc80797a..3cf0e5a32d9f21a5e5d38da41e5d70e09e918f95 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/ipv4/netfilter/ip_tables.c
 +++ b/net/ipv4/netfilter/ip_tables.c
-@@ -307,6 +307,33 @@ struct ipt_entry *ipt_next_entry(const s
+@@ -310,6 +310,33 @@ struct ipt_entry *ipt_next_entry(const s
        return (void *)entry + entry->next_offset;
  }
  
@@ -34,7 +34,7 @@
  /* Returns one of the generic firewall policies, like NF_ACCEPT. */
  unsigned int
  ipt_do_table(struct sk_buff *skb,
-@@ -331,6 +358,25 @@ ipt_do_table(struct sk_buff *skb,
+@@ -334,6 +361,25 @@ ipt_do_table(struct sk_buff *skb,
        ip = ip_hdr(skb);
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
@@ -60,7 +60,7 @@
        /* We handle fragments by dealing with the first fragment as
         * if it was a normal packet.  All other fragments are treated
         * normally, except that they will NEVER match rules that ask
-@@ -345,18 +391,6 @@ ipt_do_table(struct sk_buff *skb,
+@@ -348,18 +394,6 @@ ipt_do_table(struct sk_buff *skb,
        acpar.family  = NFPROTO_IPV4;
        acpar.hooknum = hook;