All of lore.kernel.org
 help / color / mirror / Atom feed
From: Samuel Jean <sj-netfilter@cookinglinux.org>
To: netfilter-devel@lists.netfilter.org
Subject: Re: [PATCH] ipt_hashlimit.c: avoid data corruption on checkentry
Date: Tue, 01 Feb 2005 23:14:18 -0500	[thread overview]
Message-ID: <4200539A.6000408@cookinglinux.org> (raw)
In-Reply-To: <42005218.5000401@cookinglinux.org>

[-- Attachment #1: Type: text/plain, Size: 959 bytes --]

Samuel Jean wrote:
> --- net/ipv4/netfilter/ipt_hashlimit.c.bk10     2005-02-01 
> 20:41:33.000000000 -0500
> +++ net/ipv4/netfilter/ipt_hashlimit.c  2005-02-01 22:49:48.000000000 -0500
> @@ -97,7 +97,7 @@ struct ipt_hashlimit_htable {
>         struct list_head hash[0];       /* hashtable itself */
>  };
> 
> -static DECLARE_RWLOCK(hashlimit_lock); /* protects htables list */
> +static DECLARE_LOCK(hashlimit_lock);   /* protects htables list */
>  static LIST_HEAD(hashlimit_htables);
>  static kmem_cache_t *hashlimit_cachep;
> 
> @@ -174,12 +174,17 @@ __dsthash_free(struct ipt_hashlimit_htab
>         atomic_dec(&ht->count);
>  }
>  static void htable_gc(unsigned long htlong);
> -
> -static int htable_create(struct ipt_hashlimit_info *minfo)
> +static struct ipt_hashlimit_htable *htable_find_get(char *name);

> +static void htable_put(struct ipt_hashlimit_htable *hinfo);
Please remove this ^^
or get the attached patch. Sorry, bad code review..

[-- Attachment #2: ipt_hashlimit.c-avoid-data-corruption.patch --]
[-- Type: text/x-patch, Size: 3603 bytes --]

--- net/ipv4/netfilter/ipt_hashlimit.c.bk10	2005-02-01 20:41:33.000000000 -0500
+++ net/ipv4/netfilter/ipt_hashlimit.c	2005-02-01 23:12:02.000000000 -0500
@@ -97,7 +97,7 @@ struct ipt_hashlimit_htable {
 	struct list_head hash[0];	/* hashtable itself */
 };
 
-static DECLARE_RWLOCK(hashlimit_lock);	/* protects htables list */
+static DECLARE_LOCK(hashlimit_lock);	/* protects htables list */
 static LIST_HEAD(hashlimit_htables);
 static kmem_cache_t *hashlimit_cachep;
 
@@ -174,12 +174,16 @@ __dsthash_free(struct ipt_hashlimit_htab
 	atomic_dec(&ht->count);
 }
 static void htable_gc(unsigned long htlong);
-
-static int htable_create(struct ipt_hashlimit_info *minfo)
+static struct ipt_hashlimit_htable *htable_find_get(char *name);
+	
+static struct ipt_hashlimit_htable *
+htable_create(struct ipt_hashlimit_info *minfo)
 {
 	int i;
 	unsigned int size;
-	struct ipt_hashlimit_htable *hinfo;
+	struct ipt_hashlimit_htable *hinfo, *s_hinfo;
+
+	MUST_BE_UNLOCKED(&hashlimit_lock);
 
 	if (minfo->cfg.size)
 		size = minfo->cfg.size;
@@ -196,9 +200,8 @@ static int htable_create(struct ipt_hash
 			+ (sizeof(struct list_head) * size));
 	if (!hinfo) {
 		printk(KERN_ERR "ipt_hashlimit: Unable to create hashtable\n");
-		return -1;
+		return NULL;
 	}
-	minfo->hinfo = hinfo;
 
 	/* copy match config into hashtable config */
 	memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
@@ -215,10 +218,12 @@ static int htable_create(struct ipt_hash
 	atomic_set(&hinfo->use, 1);
 	hinfo->rnd = 0;
 	spin_lock_init(&hinfo->lock);
+
+	/* FIXME: This could lead to duplicated proc entries, no ? --peejix */
 	hinfo->pde = create_proc_entry(minfo->name, 0, hashlimit_procdir);
 	if (!hinfo->pde) {
 		vfree(hinfo);
-		return -1;
+		return NULL;
 	}
 	hinfo->pde->proc_fops = &dl_file_ops;
 	hinfo->pde->data = hinfo;
@@ -229,11 +234,22 @@ static int htable_create(struct ipt_hash
 	hinfo->timer.function = htable_gc;
 	add_timer(&hinfo->timer);
 
-	WRITE_LOCK(&hashlimit_lock);
+	LOCK_BH(&hashlimit_lock);
+	if ((s_hinfo = htable_find_get(minfo->name))) {
+		/* avoid data corruption */
+		UNLOCK_BH(&hashlimit_lock);
+		remove_proc_entry(minfo->name, hashlimit_procdir);
+		if (timer_pending(&hinfo->timer))
+			del_timer(&hinfo->timer);
+		
+		vfree(hinfo);
+		return s_hinfo;
+	}
+	
 	list_add(&hinfo->list, &hashlimit_htables);
-	WRITE_UNLOCK(&hashlimit_lock);
+	UNLOCK_BH(&hashlimit_lock);
 
-	return 0;
+	return hinfo;
 }
 
 static int select_all(struct ipt_hashlimit_htable *ht, struct dsthash_ent *he)
@@ -295,15 +311,14 @@ static struct ipt_hashlimit_htable *htab
 {
 	struct ipt_hashlimit_htable *hinfo;
 
-	READ_LOCK(&hashlimit_lock);
+	MUST_BE_LOCKED(&hashlimit_lock);
+	
 	list_for_each_entry(hinfo, &hashlimit_htables, list) {
 		if (!strcmp(name, hinfo->pde->name)) {
 			atomic_inc(&hinfo->use);
-			READ_UNLOCK(&hashlimit_lock);
 			return hinfo;
 		}
 	}
-	READ_UNLOCK(&hashlimit_lock);
 
 	return NULL;
 }
@@ -311,9 +326,9 @@ static struct ipt_hashlimit_htable *htab
 static void htable_put(struct ipt_hashlimit_htable *hinfo)
 {
 	if (atomic_dec_and_test(&hinfo->use)) {
-		WRITE_LOCK(&hashlimit_lock);
+		LOCK_BH(&hashlimit_lock);
 		list_del(&hinfo->list);
-		WRITE_UNLOCK(&hashlimit_lock);
+		UNLOCK_BH(&hashlimit_lock);
 		htable_destroy(hinfo);
 	}
 }
@@ -531,8 +546,11 @@ hashlimit_checkentry(const char *tablena
 	if (!r->cfg.expire)
 		return 0;
 
+	LOCK_BH(&hashlimit_lock);
 	r->hinfo = htable_find_get(r->name);
-	if (!r->hinfo && (htable_create(r) != 0)) {
+	UNLOCK_BH(&hashlimit_lock);
+	
+	if (!r->hinfo && ((r->hinfo = htable_create(r)) == NULL)) {
 		return 0;
 	}
 

  reply	other threads:[~2005-02-02  4:14 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-02  4:07 [PATCH] ipt_hashlimit.c: avoid data corruption on checkentry Samuel Jean
2005-02-02  4:14 ` Samuel Jean [this message]
2005-02-15  0:52 ` Harald Welte
2005-02-15  4:04   ` Samuel Jean
2005-02-22 11:35     ` Harald Welte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4200539A.6000408@cookinglinux.org \
    --to=sj-netfilter@cookinglinux.org \
    --cc=netfilter-devel@lists.netfilter.org \
    --cc=sjean@cookinglinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.