[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1338621438.2760.1679.camel@edumazet-glaptop>
Date: Sat, 02 Jun 2012 09:17:18 +0200
From: Eric Dumazet <eric.dumazet@...il.com>
To: Alan Cox <alan@...rguk.ukuu.org.uk>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
Alan Cox <alan@...ux.intel.com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Jens Axboe <jaxboe@...ionio.com>
Subject: Re: [PATCH] tty: add lockdep annotations
On Fri, 2012-06-01 at 22:59 +0200, Eric Dumazet wrote:
> On Fri, 2012-06-01 at 21:56 +0100, Alan Cox wrote:
> > > Yes, tty->driver deref is ok (tty points to valid memory), but crash is
> > > on tty->driver->ops (driver points to freed/illegal memory)
> > >
> > > using slub_debug=FZPU, I can indeed see RDI=6b6b6b6b6b6b6b6b
> >
> > driver and driver->ops is basically const and it's not what you'd expect
> > from a tty refcount bug. The driver side puts shouldn't have changed but
> > I'll take a look over that patch and the error paths closely again just
> > in case.
>
> right
>
> The code looks like :
> ...
> call mcount
> mov %rdi,%rbx
> mov 0x10(%rdi),%rdi tty->driver
> <> mov 0xf8(%rdi),%rax CRASH
>
> So tty was freed an tty->driver contains 6b6b6b6b6b6b6b6b
>
>
Here is the patch I am currently testing (need to boot the machine ~50
times to make sure it is the right fix)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 9e930c0..128a95b 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1479,13 +1479,14 @@ static void release_one_tty(struct work_struct *work)
struct tty_struct *tty =
container_of(work, struct tty_struct, hangup_work);
struct tty_driver *driver = tty->driver;
+ struct module *module = driver->owner;
if (tty->ops->cleanup)
tty->ops->cleanup(tty);
tty->magic = 0;
tty_driver_kref_put(driver);
- module_put(driver->owner);
+ module_put(module);
spin_lock(&tty_files_lock);
list_del_init(&tty->tty_files);
@@ -2005,11 +2006,15 @@ retry_open:
filp->f_op = &tty_fops;
goto retry_open;
}
- tty_unlock(tty);
-
+ /*
+ * Must acquire both mutexes in right order,
+ * and keep a reference on tty, so dont call tty_unlock() !
+ */
+ mutex_unlock(&tty->legacy_mutex);
mutex_lock(&tty_mutex);
- tty_lock(tty);
+ mutex_lock(&tty->legacy_mutex);
+
spin_lock_irq(¤t->sighand->siglock);
if (!noctty &&
current->signal->leader &&
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists