netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Dumazet <eric.dumazet@gmail.com>
To: Patrick McHardy <kaber@trash.net>
Cc: Ingo Molnar <mingo@elte.hu>, David Miller <davem@davemloft.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	torvalds@linux-foundation.org, akpm@linux-foundation.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pablo Neira Ayuso <pablo@netfilter.org>
Subject: Re: [bug] __nf_ct_refresh_acct(): WARNING: at lib/list_debug.c:30 __list_add+0x7d/0xad()
Date: Thu, 18 Jun 2009 17:46:11 +0200	[thread overview]
Message-ID: <4A3A6143.3040607@gmail.com> (raw)
In-Reply-To: <4A3A5599.4080906@trash.net>

Patrick McHardy a écrit :
> Patrick McHardy wrote:
>> Eric Dumazet wrote:
>>>> a test-box still triggered this crash overnight:
>>>>
>>>> [  252.433471] ------------[ cut here ]------------
>>>> [  252.436031] WARNING: at lib/list_debug.c:30 __list_add+0x95/0xa0()
>>>> ...
>>>> With your patch (repeated below) applied. Is Patrick's alternative
>>>> patch supposed to fix something that yours does not?
>>>
>>> Hmm, not really, Patrick patch should fix same problem, but without
>>> extra locking
>>> as mine.
>>>
>>> This new stack trace is somewhat different, as corruption is detected
>>> in the add_timer()
>>> call in __nf_conntrack_confirm()
>>>
>>> So there is another problem. CCed Pablo Neira Ayuso who added some stuff
>>> in netfilter and timeout logic recently.
>>
>> That timeout logic shouldn't be relevant in this case, its only
>> activated when netlink event delivery is used, a userspace process
>> is actually listening and it has the socket marked for reliable
>> delivery.
>>
>> I think its still the same problem, the detection is just noticed
>> at a different point.
> 
> I can't find anything wrong with the conntrack timer use itself.
> Since its the timer base that is corrupted, its possible that
> something else is using timers incorrectly and conntrack just
> happens to hit the problem afterwards, but it seems rather
> unlikely since the first backtrace originated in a network driver,
> the second one in the socket layer.
> 
> But I've noticed a different problem, the lockless lookup might
> incorrectly return an conntrack entry that is supposed to be
> invisible. This can happen because we only check for equal tuples
> and !atomic_inc_not_zero(refcnt), but the conntrack can be removed
> from the lists and still have references to it. It should never
> have an active timer at that point however, so all following
> mod_timer_pending() calls *should* do nothing unless I'm missing
> something.
> 
> Ingo, could you please try whether this patch (combined with the
> last one) makes any difference? Enabling CONFIG_NETFILTER_DEBUG
> could also help.
> 
> 

Interesting !

In my own analysis, I found death_by_timeout() might be problematic,
with RCU and lockless lookups.

static void death_by_timeout(unsigned long ul_conntrack)
{
        struct nf_conn *ct = (void *)ul_conntrack;

        if (!test_bit(IPS_DYING_BIT, &ct->status) &&
            unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) {
                /* destroy event was not delivered */
                nf_ct_delete_from_lists(ct);
<< HERE >>

                nf_ct_insert_dying_list(ct);
                return;
        }
        set_bit(IPS_DYING_BIT, &ct->status);
        nf_ct_delete_from_lists(ct);
        nf_ct_put(ct);
}


We delete ct from a list and insert it in a new list.

I believe a reader could "*catch*" ct while doing a lookup and miss the end
of its chain. (nulls algo check the null value at the end of lookup and can
decide to restart the lookup if the null value is not the expected one)

We need to change nf_conntrack_init_net() and use a different "null" value,
guaranteed not being used in regular lists

Patch follows :

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5f72b94..5276a2d 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1267,13 +1267,19 @@ err_cache:
 	return ret;
 }
 
+/*
+ * We need to use special "null" values, not used in hash table
+ */
+#define UNCONFIRMED_NULLS_VAL	((1<<30)+0)
+#define DYING_NULLS_VAL		((1<<30)+1)
+
 static int nf_conntrack_init_net(struct net *net)
 {
 	int ret;
 
 	atomic_set(&net->ct.count, 0);
-	INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, 0);
-	INIT_HLIST_NULLS_HEAD(&net->ct.dying, 0);
+	INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL);
+	INIT_HLIST_NULLS_HEAD(&net->ct.dying, DYING_NULLS_VAL);
 	net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
 	if (!net->ct.stat) {
 		ret = -ENOMEM;

  reply	other threads:[~2009-06-18 15:46 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-15 12:04 [GIT]: Networking David Miller
2009-06-16  9:15 ` Ingo Molnar
2009-06-16  9:19   ` David Miller
2009-06-16  9:33     ` Ingo Molnar
2009-06-16  9:44       ` Ingo Molnar
2009-06-16  9:44     ` Alan Cox
2009-06-16  9:48       ` Ingo Molnar
2009-06-16  9:56         ` David Miller
2009-06-16 10:11           ` Ingo Molnar
2009-06-16 10:35             ` David Miller
2009-06-16 13:38               ` Eric Dumazet
2009-06-16 14:19                 ` Eric Dumazet
2009-06-16 18:59                   ` Linus Torvalds
2009-06-16 19:08                     ` David Miller
2009-06-16 19:37                       ` Eric Dumazet
2009-06-16 20:12                         ` Eric Dumazet
2009-06-17  6:41                           ` [PATCH] net: correct off-by-one write allocations reports Eric Dumazet
2009-06-17 11:31                             ` [PATCH] atm: sk_wmem_alloc initial value is one Eric Dumazet
2009-06-18  2:06                               ` David Miller
2009-06-18  2:05                             ` [PATCH] net: correct off-by-one write allocations reports David Miller
2009-06-17 11:32                           ` [GIT]: Networking David Miller
2009-06-16  9:21   ` David Miller
2009-06-16  9:26     ` Ingo Molnar
2009-06-16 10:47   ` David Miller
2009-06-16 10:53     ` Ingo Molnar
2009-06-16 12:24       ` Ingo Molnar
2009-06-16 12:39         ` David Miller
2009-06-17  9:21         ` [bug] __nf_ct_refresh_acct(): WARNING: at lib/list_debug.c:30 __list_add+0x7d/0xad() Ingo Molnar
2009-06-17 10:18           ` Eric Dumazet
2009-06-17 11:08             ` Ingo Molnar
2009-06-17 11:35               ` David Miller
2009-06-18  5:23               ` Ingo Molnar
2009-06-18  5:58                 ` Eric Dumazet
2009-06-18  9:47                   ` Patrick McHardy
2009-06-18 14:56                     ` Patrick McHardy
2009-06-18 15:46                       ` Eric Dumazet [this message]
2009-06-18 16:09                         ` Patrick McHardy
2009-06-18 16:13                           ` Pablo Neira Ayuso
2009-06-18 22:46                           ` [PATCH] netfilter: conntrack: death_by_timeout() fix Eric Dumazet
2009-06-19 11:15                             ` Patrick McHardy
2009-06-20 15:47                       ` [bug] __nf_ct_refresh_acct(): WARNING: at lib/list_debug.c:30 __list_add+0x7d/0xad() Ingo Molnar
2009-06-20 15:56                         ` Patrick McHardy
2009-06-17 11:38             ` Patrick McHardy
2009-06-17 11:51               ` Patrick McHardy
2009-06-17 11:55               ` Eric Dumazet
2009-06-17 12:00                 ` Patrick McHardy
2009-06-17 12:33                   ` Eric Dumazet
2009-06-17 12:36                     ` Patrick McHardy
2009-06-17 13:27                       ` Eric Dumazet
2009-06-17 13:29                         ` Patrick McHardy
2009-06-17 14:23                           ` Patrick McHardy
2009-06-17 15:29                             ` Eric Dumazet
2009-06-17 15:34                               ` Patrick McHardy
2009-06-18 23:18 ` [GIT]: Networking Tilman Schmidt
2009-06-19  3:36   ` David Miller

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=4A3A6143.3040607@gmail.com \
    --to=eric.dumazet@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=kaber@trash.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=netdev@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).