1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

kernel: fix kernel panic when traffic goes over the network.

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22246 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
hauke
2010-07-17 13:01:16 +00:00
parent 124bd99740
commit c5e0e0ad5c

View File

@@ -75,7 +75,7 @@
} }
/* for const-correctness */ /* 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; const struct xt_table_info *private;
struct xt_action_param acpar; struct xt_action_param acpar;
@@ -85,7 +85,8 @@
+ IP_NF_ASSERT(table->valid_hooks & (1 << hook)); + IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+ xt_info_rdlock_bh(); + xt_info_rdlock_bh();
+ private = table->private; + 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]); + e = get_entry(table_base, private->hook_entry[hook]);
+ +
+ if (e->target_offset <= sizeof(struct ipt_entry) && + if (e->target_offset <= sizeof(struct ipt_entry) &&
@@ -105,7 +106,25 @@
indev = in ? in->name : nulldevname; indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname; outdev = out ? out->name : nulldevname;
/* We handle fragments by dealing with the first fragment as /* 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; unsigned int i;
const struct ipt_entry_match *m; const struct ipt_entry_match *m;
const struct ipt_entry_target *t; const struct ipt_entry_target *t;
@@ -113,11 +132,10 @@
e = (struct ipt_entry *)(loc_cpu_entry + off); e = (struct ipt_entry *)(loc_cpu_entry + off);
if (copy_to_user(userptr + off if (copy_to_user(userptr + off
@@ -979,6 +1026,14 @@ copy_entries_to_user(unsigned int total_ @@ -980,6 +1021,14 @@ copy_entries_to_user(unsigned int total_
ret = -EFAULT;
goto free_counters; goto free_counters;
} }
+
+ flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH; + flags = e->ip.flags & ~IPT_F_NO_DEF_MATCH;
+ if (copy_to_user(userptr + off + if (copy_to_user(userptr + off
+ + offsetof(struct ipt_entry, ip.flags), + + offsetof(struct ipt_entry, ip.flags),
@@ -125,6 +143,7 @@
+ ret = -EFAULT; + ret = -EFAULT;
+ goto free_counters; + goto free_counters;
+ } + }
+
for (i = sizeof(struct ipt_entry); for (i = sizeof(struct ipt_entry);
i < e->target_offset; i < e->target_offset;
i += m->u.match_size) {