kernel: fix kernel panic when traffic goes over the network.
SVN-Revision: 22246
This commit is contained in:
parent
2e05035bb1
commit
bcec3ad0e9
1 changed files with 26 additions and 7 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue