Re: Resend: One bug in the xt_hashlimit.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sunday 2012-12-16 16:19, Feng Gao wrote:
>
>Hi Harald & Jan,
>
>Because there is no any response for this issue,so I send the egmail again a
>s a reminder.

Sorry to not have responded. This sort of went under the radar since
netfilter-devel was initially not Cced. More answers to the patch
below.

>The following codes are from function "hashlimit_mt".
>dh = dsthash_find(hinfo, &dst);
>if (dh == NULL) {
>dh = dsthash_alloc_init(hinfo, &dst);
>
>When two or more threads invoke dsthash_find(hinfo, &dst) at the same time
>and fail to find the dh, then all of them will enter the dsthash_alloc_init
>to create one new node.
>As a result, it will casue that these multiple threads create multle nodes
>with same IP. It is not expected behavior.

>--- net/netfilter/xt_hashlimit.c.orig	2012-12-02 13:54:45.376382165 +0800
>+++ net/netfilter/xt_hashlimit.c	2012-12-02 13:59:32.083381142 +0800
>@@ -157,11 +157,20 @@ dsthash_find(const struct xt_hashlimit_h
> /* allocate dsthash_ent, initialize dst, put in htable and lock it */
> static struct dsthash_ent *
> dsthash_alloc_init(struct xt_hashlimit_htable *ht,
>-		   const struct dsthash_dst *dst)
>+		   const struct dsthash_dst *dst,
>+		   bool *new_node)
> {
> 	struct dsthash_ent *ent;
> 
> 	spin_lock(&ht->lock);
>+
>+	ent = dsthash_find(ht, dst);

Hm. In hashlimit_mt(), dsthash_find() has already been called once
(within a RCU_bh section), and now you are doing the lookup again
(within spin_lock section).

>+	if (ent) {        

You have trailing squatspaces (remove them). I suggest that you
use `mcedit` or `git log -1 -p`, as both these tools highlight
such unwanted trailing spaces.

>@@ -539,7 +555,7 @@ hashlimit_mt(const struct sk_buff *skb, 
> 		dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
> 		rateinfo_recalc(dh, now);
> 	}
>-
>+	
> 	if (dh->rateinfo.credit >= dh->rateinfo.cost) {
> 		/* below the limit */
> 		dh->rateinfo.credit -= dh->rateinfo.cost;

Same spacing issue here.

====

What would you think of the following patch?

diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 26a668a..0d17032 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -591,9 +591,11 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
 		goto hotdrop;
 
 	rcu_read_lock_bh();
+	spin_lock_bh();
 	dh = dsthash_find(hinfo, &dst);
 	if (dh == NULL) {
 		dh = dsthash_alloc_init(hinfo, &dst);
+		spin_unlock_bh();
 		if (dh == NULL) {
 			rcu_read_unlock_bh();
 			goto hotdrop;
@@ -601,6 +603,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
 		dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
 		rateinfo_init(dh, hinfo);
 	} else {
+		spin_unlock_bh();
 		/* update expiration timeout */
 		dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
 		rateinfo_recalc(dh, now, hinfo->cfg.mode);
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux