diff options
author | David S. Miller <davem@davemloft.net> | 2005-10-13 17:41:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-10-13 17:41:23 -0400 |
commit | c8923c6b852d3a97c1faad0566e38fca330375a7 (patch) | |
tree | eb79e97c5468bba641c7a34b83514876f4902cf2 /net/ipv6 | |
parent | c931488cc4619eecfe68a2f046b5898fddc2f904 (diff) |
[NETFILTER]: Fix OOPSes on machines with discontiguous cpu numbering.
Original patch by Harald Welte, with feedback from Herbert Xu
and testing by Sébastien Bernard.
EBTABLES, ARP tables, and IP/IP6 tables all assume that cpus
are numbered linearly. That is not necessarily true.
This patch fixes that up by calculating the largest possible
cpu number, and allocating enough per-cpu structure space given
that.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 2da514b16d95..b03e90649eb5 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/semaphore.h> | 29 | #include <asm/semaphore.h> |
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/cpumask.h> | ||
31 | 32 | ||
32 | #include <linux/netfilter_ipv6/ip6_tables.h> | 33 | #include <linux/netfilter_ipv6/ip6_tables.h> |
33 | 34 | ||
@@ -950,8 +951,10 @@ translate_table(const char *name, | |||
950 | } | 951 | } |
951 | 952 | ||
952 | /* And one copy for every other CPU */ | 953 | /* And one copy for every other CPU */ |
953 | for (i = 1; i < num_possible_cpus(); i++) { | 954 | for_each_cpu(i) { |
954 | memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i, | 955 | if (i == 0) |
956 | continue; | ||
957 | memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i, | ||
955 | newinfo->entries, | 958 | newinfo->entries, |
956 | SMP_ALIGN(newinfo->size)); | 959 | SMP_ALIGN(newinfo->size)); |
957 | } | 960 | } |
@@ -973,6 +976,7 @@ replace_table(struct ip6t_table *table, | |||
973 | unsigned int i; | 976 | unsigned int i; |
974 | 977 | ||
975 | for (i = 0; i < num_possible_cpus(); i++) { | 978 | for (i = 0; i < num_possible_cpus(); i++) { |
979 | for_each_cpu(i) { | ||
976 | table_base = | 980 | table_base = |
977 | (void *)newinfo->entries | 981 | (void *)newinfo->entries |
978 | + TABLE_OFFSET(newinfo, i); | 982 | + TABLE_OFFSET(newinfo, i); |
@@ -1019,7 +1023,7 @@ get_counters(const struct ip6t_table_info *t, | |||
1019 | unsigned int cpu; | 1023 | unsigned int cpu; |
1020 | unsigned int i; | 1024 | unsigned int i; |
1021 | 1025 | ||
1022 | for (cpu = 0; cpu < num_possible_cpus(); cpu++) { | 1026 | for_each_cpu(cpu) { |
1023 | i = 0; | 1027 | i = 0; |
1024 | IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), | 1028 | IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), |
1025 | t->size, | 1029 | t->size, |
@@ -1153,7 +1157,8 @@ do_replace(void __user *user, unsigned int len) | |||
1153 | return -ENOMEM; | 1157 | return -ENOMEM; |
1154 | 1158 | ||
1155 | newinfo = vmalloc(sizeof(struct ip6t_table_info) | 1159 | newinfo = vmalloc(sizeof(struct ip6t_table_info) |
1156 | + SMP_ALIGN(tmp.size) * num_possible_cpus()); | 1160 | + SMP_ALIGN(tmp.size) * |
1161 | (highest_possible_processor_id()+1)); | ||
1157 | if (!newinfo) | 1162 | if (!newinfo) |
1158 | return -ENOMEM; | 1163 | return -ENOMEM; |
1159 | 1164 | ||
@@ -1467,7 +1472,8 @@ int ip6t_register_table(struct ip6t_table *table, | |||
1467 | = { 0, 0, 0, { 0 }, { 0 }, { } }; | 1472 | = { 0, 0, 0, { 0 }, { 0 }, { } }; |
1468 | 1473 | ||
1469 | newinfo = vmalloc(sizeof(struct ip6t_table_info) | 1474 | newinfo = vmalloc(sizeof(struct ip6t_table_info) |
1470 | + SMP_ALIGN(repl->size) * num_possible_cpus()); | 1475 | + SMP_ALIGN(repl->size) * |
1476 | (highest_possible_processor_id()+1)); | ||
1471 | if (!newinfo) | 1477 | if (!newinfo) |
1472 | return -ENOMEM; | 1478 | return -ENOMEM; |
1473 | 1479 | ||