netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Cyrill Gorcunov <gorcunov@gmail.com>
To: Michal Ostrowski <mostrows@gmail.com>
Cc: Eric Dumazet <eric.dumazet@gmail.com>,
	Denys Fedoryschenko <denys@visp.net.lb>,
	netdev <netdev@vger.kernel.org>,
	linux-ppp@vger.kernel.org, paulus@samba.org,
	mostrows@earthlink.net
Subject: Re: kernel panic in latest vanilla stable, while using nameif with "alive" pppoe interfaces
Date: Mon, 19 Oct 2009 19:50:34 +0400	[thread overview]
Message-ID: <20091019155034.GA5233@lenovo> (raw)
In-Reply-To: <e6d1cecd0910190619t3e009e1by49cc8f7307eb7cdb@mail.gmail.com>

[Michal Ostrowski - Mon, Oct 19, 2009 at 08:19:23AM -0500]
|
| The entire scheme for managing net namespaces seems unsafe.  We depend
| on synchronization via pn->hash_lock, but have no guarantee of the
| existence of the "net" object -- hence no way to ensure the existence
| of the lock itself.  This should be relatively easy to fix though as
| we should be able to get/put the net namespace as we add remove
| objects to/from the pppoe hash.
|

Hmm... it seems not. The only possible scenario I see (for such nonexistence
namespace is that when it was cached via RCU and returned before grace period
elapsed, so perhaps we need to call synchronize_net somewhere).

| 
| Once you solve this existence issue, the flush_lock can be eliminated
| altogether since all of the relevant code paths already depend on a
| write_lock_bh(&pn->hash_lock), and that's the lock that should be use
| to protect the pppoe_dev field.
| 
| Another patch to follow later...
| 
| --
| Michal Ostrowski
| mostrows@gmail.com
| 
| 
| 
| On Mon, Oct 19, 2009 at 7:36 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
| > Michal Ostrowski a écrit :
| >> Here's my theory on this after an inital look...
| >>
| >> Looking at the oops report and disassembly of the actual module binary
| >> that caused the oops, one can deduce that:
| >>
| >> Execution was in pppoe_flush_dev().  %ebx contained the pointer "struct
| >> pppox_sock *po", which is what we faulted on, excuting "cmp %eax, 0x190(%ebx)".
| >> %ebx value was 0xffffffff (hence we got "NULL pointer dereference at 0x18f").
| >>
| >> At this point "i" (stored in %esi) is 15 (valid), meaning that we got a value
| >> of 0xffffffff in pn->hash_table[i].
| >>
| >>>From this I'd hypothesize that the combination of dev_put() and release_sock()
| >> may have allowed us to free "pn".  At the bottom of the loop we alreayd
| >> recognize that since locks are dropped we're responsible for handling
| >> invalidation of objects, and perhaps that should be extended to "pn" as well.
| >> --
| >> Michal Ostrowski
| >> mostrows@gmail.com
| >>
| >>
| >
| > Looking at this stuff, I do believe flush_lock protection is not
| > properly done.
| >
| > At the end of pppoe_connect() for example we can find :
| >
| > err_put:
| >        if (po->pppoe_dev) {
| >                dev_put(po->pppoe_dev);
| >                po->pppoe_dev = NULL;
| >        }

Yep, this is unsafe, thanks!

| >
| > This is done without any protection, and can therefore clash with
| > pppoe_flush_dev() :
| >
| >        spin_lock(&flush_lock);
| >        po->pppoe_dev = NULL; /* ppoe_dev can already be NULL before this point */
| >        spin_unlock(&flush_lock);
| >
| >        dev_put(dev);    /* oops */
| >
| 

Denys, could you check if the patch below help?

	-- Cyrill
---
 drivers/net/pppoe.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6.git/drivers/net/pppoe.c
=====================================================================
--- linux-2.6.git.orig/drivers/net/pppoe.c
+++ linux-2.6.git/drivers/net/pppoe.c
@@ -312,9 +312,9 @@ static void pppoe_flush_dev(struct net_d
 			}
 			sk = sk_pppox(po);
 			spin_lock(&flush_lock);
+			dev_put(po->pppoe_dev);
 			po->pppoe_dev = NULL;
 			spin_unlock(&flush_lock);
-			dev_put(dev);
 
 			/* We always grab the socket lock, followed by the
 			 * hash_lock, in that order.  Since we should
@@ -708,10 +708,12 @@ end:
 	release_sock(sk);
 	return error;
 err_put:
+	spin_lock(&flush_lock);
 	if (po->pppoe_dev) {
 		dev_put(po->pppoe_dev);
 		po->pppoe_dev = NULL;
 	}
+	spin_unlock(&flush_lock);
 	goto end;
 }
 

  reply	other threads:[~2009-10-19 15:56 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-18 21:02 kernel panic in latest vanilla stable, while using nameif with "alive" pppoe interfaces Denys Fedoryschenko
2009-10-19  3:34 ` Michal Ostrowski
2009-10-19 11:36   ` Denys Fedoryschenko
2009-10-19 12:01   ` Denys Fedoryschenko
2009-10-19 12:36   ` Eric Dumazet
2009-10-19 13:19     ` Michal Ostrowski
2009-10-19 15:50       ` Cyrill Gorcunov [this message]
2009-10-19 16:05         ` Michal Ostrowski
2009-10-19 17:12           ` Eric Dumazet
2009-10-19 18:07             ` Michal Ostrowski
2009-10-19 18:44               ` Eric Dumazet
2009-10-19 19:29                 ` Cyrill Gorcunov
2009-10-19 20:54                 ` Michal Ostrowski
2009-10-20  3:42                   ` Eric Dumazet
2009-10-20  5:02                     ` Cyrill Gorcunov
2009-10-20  5:05                       ` Eric Dumazet
2009-10-20  5:17                         ` Cyrill Gorcunov
2009-10-20  6:04                           ` Cyrill Gorcunov
2009-10-19 20:57                 ` Cyrill Gorcunov
2009-10-19 21:22                   ` Michal Ostrowski
2009-10-20  0:08                     ` Denys Fedoryschenko
2009-10-20  3:04                       ` Cyrill Gorcunov
2009-10-20 11:36                         ` Denys Fedoryschenko
2009-10-20 11:50                           ` Cyrill Gorcunov
2009-10-20 11:52                             ` Denys Fedoryschenko
2009-10-20 13:42                               ` Cyrill Gorcunov
2009-10-20 13:50                                 ` Denys Fedoryschenko
2009-10-20 13:59                                   ` Cyrill Gorcunov
2009-10-20 14:20                                     ` Denys Fedoryschenko
2009-10-20 14:23                                       ` Cyrill Gorcunov
2009-10-20 19:08                                       ` Cyrill Gorcunov
2009-10-23 15:18                                         ` Cyrill Gorcunov
2009-10-25 18:10                                           ` Denys Fedoryschenko
2009-10-20  2:28                     ` 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=20091019155034.GA5233@lenovo \
    --to=gorcunov@gmail.com \
    --cc=denys@visp.net.lb \
    --cc=eric.dumazet@gmail.com \
    --cc=linux-ppp@vger.kernel.org \
    --cc=mostrows@earthlink.net \
    --cc=mostrows@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=paulus@samba.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).