From patchwork Tue Sep 10 21:12:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Smith X-Patchwork-Id: 274074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 387072C01EA for ; Wed, 11 Sep 2013 07:13:04 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751490Ab3IJVNC (ORCPT ); Tue, 10 Sep 2013 17:13:02 -0400 Received: from mail.uptheinter.net ([77.74.196.236]:60281 "EHLO mail.uptheinter.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751326Ab3IJVNA (ORCPT ); Tue, 10 Sep 2013 17:13:00 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.uptheinter.net (Postfix) with ESMTP id 6F88BA30D3 for ; Tue, 10 Sep 2013 22:12:57 +0100 (BST) X-DKIM: Sendmail DKIM Filter v2.7.2 mail.uptheinter.net 6F88BA30D3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa; s=default; t=1378847577; bh=scb vIKGD5AfGMgg+9TWshI6AlddQSRJMY6ReO6JaFJk=; h=From:To:Subject:Date: Message-Id; b=ylRJBQAXntj3NVm4Kl4r81noiDwdXb2vcLgsNRPicBJEDrn4u4wV L5X3gztWso3wEBazqxyZfwV2LKpq2E7PCdV4GTtKK4MICtTmd3GAAD4rt9C+Nx+r0aV QDhjZMAOCytJFG5PPBnrJP+21bwA0SVC2V7rYcIgJ4XTszxxobc0= X-Virus-Scanned: amavisd-new at Received: from mail.uptheinter.net ([127.0.0.1]) by localhost (vps2.uptheinter.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 7tB6LgDPfyGG for ; Tue, 10 Sep 2013 22:12:46 +0100 (BST) From: Oliver To: netfilter-devel@vger.kernel.org Subject: [PATCH] netfilter: ipset: Fix serious failure in CIDR tracking Date: Tue, 10 Sep 2013 23:12:44 +0200 Message-Id: <1378847564-35416-1-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> X-Mailer: git-send-email 1.8.3.2 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Oliver Smith 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 clean up the last element afterwards. Signed-off-by: Oliver Smith --- kernel/net/netfilter/ipset/ip_set_hash_gen.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h index 7a5b776..f0f0c8d 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h @@ -311,15 +311,17 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n) for (i = 0; i < nets_length - 1 && h->nets[i].cidr[n] != cidr; i++) ; - h->nets[i].nets[n]--; - - if (h->nets[i].nets[n] != 0) + if (h->nets[i+1].nets[n] == 0) { + h->nets[i].nets[n]--; return; + } for (j = i; j < nets_length - 1 && h->nets[j].nets[n]; j++) { h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; h->nets[j].nets[n] = h->nets[j + 1].nets[n]; } + h->nets[j].cidr[n] = 0; + h->nets[j].nets[n] = 0; } #endif