From 25c26c98e27180c4ffbfaef849d8b45567cae56e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 May 2014 16:56:05 -0700 Subject: [PATCH] 3.4-stable patches added patches: netfilter-can-t-fail-and-free-after-table-replacement.patch netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch --- ...ail-and-free-after-table-replacement.patch | 91 +++++++++++++++++++ ...-reserve-two-bytes-for-nf_ct_ext-len.patch | 54 +++++++++++ queue-3.4/series | 2 + 3 files changed, 147 insertions(+) create mode 100644 queue-3.4/netfilter-can-t-fail-and-free-after-table-replacement.patch create mode 100644 queue-3.4/netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch diff --git a/queue-3.4/netfilter-can-t-fail-and-free-after-table-replacement.patch b/queue-3.4/netfilter-can-t-fail-and-free-after-table-replacement.patch new file mode 100644 index 00000000000..2f206be23f5 --- /dev/null +++ b/queue-3.4/netfilter-can-t-fail-and-free-after-table-replacement.patch @@ -0,0 +1,91 @@ +From c58dd2dd443c26d856a168db108a0cd11c285bf3 Mon Sep 17 00:00:00 2001 +From: Thomas Graf +Date: Fri, 4 Apr 2014 17:57:45 +0200 +Subject: netfilter: Can't fail and free after table replacement + +From: Thomas Graf + +commit c58dd2dd443c26d856a168db108a0cd11c285bf3 upstream. + +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 +Signed-off-by: Thomas Graf +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 5 ++--- + net/ipv4/netfilter/arp_tables.c | 6 ++++-- + net/ipv4/netfilter/ip_tables.c | 6 ++++-- + net/ipv6/netfilter/ip6_tables.c | 6 ++++-- + 4 files changed, 14 insertions(+), 9 deletions(-) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -1044,10 +1044,9 @@ static int do_replace_finish(struct net + if (repl->num_counters && + copy_to_user(repl->counters, counterstmp, + repl->num_counters * sizeof(struct ebt_counter))) { +- ret = -EFAULT; ++ /* Silent error, can't fail, new table is already in place */ ++ net_warn_ratelimited("ebtables: counters copy to user failed while replacing table\n"); + } +- else +- ret = 0; + + /* decrease module count and free resources */ + EBT_ENTRY_ITERATE(table->entries, table->entries_size, +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -1039,8 +1039,10 @@ static int __do_replace(struct net *net, + + xt_free_table_info(oldinfo); + if (copy_to_user(counters_ptr, counters, +- sizeof(struct xt_counters) * num_counters) != 0) +- ret = -EFAULT; ++ sizeof(struct xt_counters) * num_counters) != 0) { ++ /* Silent error, can't fail, new table is already in place */ ++ net_warn_ratelimited("arptables: counters copy to user failed while replacing table\n"); ++ } + vfree(counters); + xt_table_unlock(t); + return ret; +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -1227,8 +1227,10 @@ __do_replace(struct net *net, const char + + xt_free_table_info(oldinfo); + if (copy_to_user(counters_ptr, counters, +- sizeof(struct xt_counters) * num_counters) != 0) +- ret = -EFAULT; ++ sizeof(struct xt_counters) * num_counters) != 0) { ++ /* Silent error, can't fail, new table is already in place */ ++ net_warn_ratelimited("iptables: counters copy to user failed while replacing table\n"); ++ } + vfree(counters); + xt_table_unlock(t); + return ret; +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -1236,8 +1236,10 @@ __do_replace(struct net *net, const char + + xt_free_table_info(oldinfo); + if (copy_to_user(counters_ptr, counters, +- sizeof(struct xt_counters) * num_counters) != 0) +- ret = -EFAULT; ++ sizeof(struct xt_counters) * num_counters) != 0) { ++ /* Silent error, can't fail, new table is already in place */ ++ net_warn_ratelimited("ip6tables: counters copy to user failed while replacing table\n"); ++ } + vfree(counters); + xt_table_unlock(t); + return ret; diff --git a/queue-3.4/netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch b/queue-3.4/netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch new file mode 100644 index 00000000000..051fc685823 --- /dev/null +++ b/queue-3.4/netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch @@ -0,0 +1,54 @@ +From 223b02d923ecd7c84cf9780bb3686f455d279279 Mon Sep 17 00:00:00 2001 +From: Andrey Vagin +Date: Fri, 28 Mar 2014 13:54:32 +0400 +Subject: netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len + +From: Andrey Vagin + +commit 223b02d923ecd7c84cf9780bb3686f455d279279 upstream. + +"len" contains sizeof(nf_ct_ext) and size of extensions. In a worst +case it can contain all extensions. Bellow you can find sizes for all +types of extensions. Their sum is definitely bigger than 256. + +nf_ct_ext_types[0]->len = 24 +nf_ct_ext_types[1]->len = 32 +nf_ct_ext_types[2]->len = 24 +nf_ct_ext_types[3]->len = 32 +nf_ct_ext_types[4]->len = 152 +nf_ct_ext_types[5]->len = 2 +nf_ct_ext_types[6]->len = 16 +nf_ct_ext_types[7]->len = 8 + +I have seen "len" up to 280 and my host has crashes w/o this patch. + +The right way to fix this problem is reducing the size of the ecache +extension (4) and Florian is going to do this, but these changes will +be quite large to be appropriate for a stable tree. + +Fixes: 5b423f6a40a0 (netfilter: nf_conntrack: fix racy timer handling with reliable) +Cc: Pablo Neira Ayuso +Cc: Patrick McHardy +Cc: Jozsef Kadlecsik +Cc: "David S. Miller" +Signed-off-by: Andrey Vagin +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_conntrack_extend.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/net/netfilter/nf_conntrack_extend.h ++++ b/include/net/netfilter/nf_conntrack_extend.h +@@ -37,8 +37,8 @@ enum nf_ct_ext_id { + /* Extensions: optional stuff which isn't permanently in struct. */ + struct nf_ct_ext { + struct rcu_head rcu; +- u8 offset[NF_CT_EXT_NUM]; +- u8 len; ++ u16 offset[NF_CT_EXT_NUM]; ++ u16 len; + char data[0]; + }; + diff --git a/queue-3.4/series b/queue-3.4/series index f53bdedb541..738d31a34b7 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -1,3 +1,5 @@ scsi-megaraid-missing-bounds-check-in-mimd_to_kioc.patch n_tty-Fix-n_tty_write-crash-when-echoing-in-raw-mode.patch blktrace-fix-accounting-of-partially-completed-requests.patch +netfilter-nf_conntrack-reserve-two-bytes-for-nf_ct_ext-len.patch +netfilter-can-t-fail-and-free-after-table-replacement.patch -- 2.47.3