From: Greg Kroah-Hartman Date: Sat, 28 Sep 2013 17:25:49 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.0.98~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6b8462dd190ab046388cc8eb90a1a7f2407a18bc;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: netfilter-ipset-fix-serious-failure-in-cidr-tracking.patch --- diff --git a/queue-3.10/netfilter-ipset-fix-serious-failure-in-cidr-tracking.patch b/queue-3.10/netfilter-ipset-fix-serious-failure-in-cidr-tracking.patch new file mode 100644 index 00000000000..8effb739174 --- /dev/null +++ b/queue-3.10/netfilter-ipset-fix-serious-failure-in-cidr-tracking.patch @@ -0,0 +1,73 @@ +From 2cf55125c64d64cc106e204d53b107094762dfdf Mon Sep 17 00:00:00 2001 +From: Oliver Smith +Date: Mon, 16 Sep 2013 20:30:57 +0200 +Subject: netfilter: ipset: Fix serious failure in CIDR tracking + +From: Oliver Smith + +commit 2cf55125c64d64cc106e204d53b107094762dfdf upstream. + +This fixes a serious bug affecting all hash types with a net element - +specifically, if a CIDR value is deleted such that none of the same size +exist any more, all larger (less-specific) values will then fail to +match. Adding back any prefix with a CIDR equal to or more specific than +the one deleted will fix it. + +Steps to reproduce: +ipset -N test hash:net +ipset -A test 1.1.0.0/16 +ipset -A test 2.2.2.0/24 +ipset -T test 1.1.1.1 #1.1.1.1 IS in set +ipset -D test 2.2.2.0/24 +ipset -T test 1.1.1.1 #1.1.1.1 IS NOT in set + +This is due to the fact that the nets counter was unconditionally +decremented prior to the iteration that shifts up the entries. Now, we +first check if there is a proceeding entry and if not, decrement it and +return. Otherwise, we proceed to iterate and then zero the last element, +which, in most cases, will already be zero. + +Signed-off-by: Oliver Smith +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/ipset/ip_set_hash_gen.h | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -325,18 +325,22 @@ mtype_add_cidr(struct htype *h, u8 cidr, + static void + mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length) + { +- u8 i, j; ++ u8 i, j, net_end = nets_length - 1; + +- for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++) +- ; +- h->nets[i].nets--; +- +- if (h->nets[i].nets != 0) +- return; +- +- for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) { +- h->nets[j].cidr = h->nets[j + 1].cidr; +- h->nets[j].nets = h->nets[j + 1].nets; ++ for (i = 0; i < nets_length; i++) { ++ if (h->nets[i].cidr != cidr) ++ continue; ++ if (h->nets[i].nets > 1 || i == net_end || ++ h->nets[i + 1].nets == 0) { ++ h->nets[i].nets--; ++ return; ++ } ++ for (j = i; j < net_end && h->nets[j].nets; j++) { ++ h->nets[j].cidr = h->nets[j + 1].cidr; ++ h->nets[j].nets = h->nets[j + 1].nets; ++ } ++ h->nets[j].nets = 0; ++ return; + } + } + #endif diff --git a/queue-3.10/series b/queue-3.10/series index 1f0d727cd74..c84484201db 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -46,3 +46,4 @@ rpc-clean-up-decoding-of-gssproxy-linux-creds.patch rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch rpc-fix-huge-kmalloc-s-in-gss-proxy.patch rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch +netfilter-ipset-fix-serious-failure-in-cidr-tracking.patch