aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2014-04-04 11:57:45 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2014-04-05 11:46:22 -0400
commitc58dd2dd443c26d856a168db108a0cd11c285bf3 (patch)
treefc3b89ed8e66d3f99f9322efc812e8c7bcd60509 /net/ipv6
parent2fec6bb6f484b1a88b4a325724234d6cfd08c918 (diff)
netfilter: Can't fail and free after table replacement
All xtables variants suffer from the defect that the copy_to_user() to copy the counters to user memory may fail after the table has already been exchanged and thus exposed. Return an error at this point will result in freeing the already exposed table. Any subsequent packet processing will result in a kernel panic. We can't copy the counters before exposing the new tables as we want provide the counter state after the old table has been unhooked. Therefore convert this into a silent error. Cc: Florian Westphal <fw@strlen.de> Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter/ip6_tables.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 710238f58aa9..e080fbbbc0e5 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1241,8 +1241,10 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1241 1241
1242 xt_free_table_info(oldinfo); 1242 xt_free_table_info(oldinfo);
1243 if (copy_to_user(counters_ptr, counters, 1243 if (copy_to_user(counters_ptr, counters,
1244 sizeof(struct xt_counters) * num_counters) != 0) 1244 sizeof(struct xt_counters) * num_counters) != 0) {
1245 ret = -EFAULT; 1245 /* Silent error, can't fail, new table is already in place */
1246 net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n");
1247 }
1246 vfree(counters); 1248 vfree(counters);
1247 xt_table_unlock(t); 1249 xt_table_unlock(t);
1248 return ret; 1250 return ret;