kernel: fix kernel panic when traffic goes over the network.
authorHauke Mehrtens <hauke@hauke-m.de>
Sat, 17 Jul 2010 13:01:16 +0000 (13:01 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 17 Jul 2010 13:01:16 +0000 (13:01 +0000)
SVN-Revision: 22246

target/linux/generic/patches-2.6.35/110-netfilter_match_speedup.patch

index b688fda..7affbb1 100644 (file)
@@ -75,7 +75,7 @@
  }
  
  /* for const-correctness */
-@@ -312,8 +338,28 @@ ipt_do_table(struct sk_buff *skb,
+@@ -312,8 +338,29 @@ ipt_do_table(struct sk_buff *skb,
        const struct xt_table_info *private;
        struct xt_action_param acpar;
  
@@ -85,7 +85,8 @@
 +      IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 +      xt_info_rdlock_bh();
 +      private = table->private;
-+      table_base = private->entries[smp_processor_id()];
++      cpu        = smp_processor_id();
++      table_base = private->entries[cpu];
 +      e = get_entry(table_base, private->hook_entry[hook]);
 +
 +      if (e->target_offset <= sizeof(struct ipt_entry) &&
        indev = in ? in->name : nulldevname;
        outdev = out ? out->name : nulldevname;
        /* We handle fragments by dealing with the first fragment as
-@@ -970,6 +1016,7 @@ copy_entries_to_user(unsigned int total_
+@@ -330,17 +377,10 @@ ipt_do_table(struct sk_buff *skb,
+       acpar.family  = NFPROTO_IPV4;
+       acpar.hooknum = hook;
+-      IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+-      xt_info_rdlock_bh();
+-      private = table->private;
+-      cpu        = smp_processor_id();
+-      table_base = private->entries[cpu];
+       jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
+       stackptr   = per_cpu_ptr(private->stackptr, cpu);
+       origptr    = *stackptr;
+-      e = get_entry(table_base, private->hook_entry[hook]);
+-
+       pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
+                table->name, hook, origptr,
+                get_entry(table_base, private->underflow[hook]));
+@@ -970,6 +1010,7 @@ copy_entries_to_user(unsigned int total_
                unsigned int i;
                const struct ipt_entry_match *m;
                const struct ipt_entry_target *t;
  
                e = (struct ipt_entry *)(loc_cpu_entry + off);
                if (copy_to_user(userptr + off
-@@ -979,6 +1026,14 @@ copy_entries_to_user(unsigned int total_
-                       ret = -EFAULT;
+@@ -980,6 +1021,14 @@ copy_entries_to_user(unsigned int total_
                        goto free_counters;
                }
-+
 +              flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
 +              if (copy_to_user(userptr + off
 +                               + offsetof(struct ipt_entry, ip.flags),
 +                      ret = -EFAULT;
 +                      goto free_counters;
 +              }
++
                for (i = sizeof(struct ipt_entry);
                     i < e->target_offset;
+                    i += m->u.match_size) {