lkml.org 
[lkml]   [2012]   [Jun]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRe: [PATCH] tty: add lockdep annotations
From
Date
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(&current->sighand->siglock);
if (!noctty &&
current->signal->leader &&



\
 
 \ /
  Last update: 2012-06-02 09:41    [from the cache]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and my Meterkast|Read the blog