
eric.dumazet at gmail
Jun 1, 2012, 1:44 PM
Post #7 of 27
(148 views)
Permalink
|
On Fri, 2012-06-01 at 11:51 -0700, Linus Torvalds wrote: > On Fri, Jun 1, 2012 at 11:17 AM, Eric Dumazet <eric.dumazet [at] gmail> wrote: > > > > About 10% of boots on my machine, and this looks like (hand written) > > > > general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC > > ... > > RIP : tty_shutdown+0x15/)x70 > > Ok, DEBUG_PAGEALLOC and with that offset fairly early in tty_shutdown, > it's almost certainly one of the accesses in the > > tty->driver->ops->remove > 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 Typical use after free... > chain when it does the (inlined) > > tty_driver_remove_tty(tty->driver, tty); > > you could check which one it is at that offset 0x15, but I think both > the ops and the driver structures should be statically allocated, so I > suspect it's the "tty" itself that is already freed. > > Odd. But yes, smells very much like a refcount issue, probably due to > broken locking. Does the problem go away if you revert commits > d29f3ef39be4 ("tty_lock: Localise the lock") and 3af502b96649 > ("tty_lock: undo the old tty_lock use on the ctty")? Tried this but seems not straightforward, and its pretty late here in France, week end starting ;) By the way, release_one_tty() uses the following racy code : tty_driver_kref_put(driver); module_put(driver->owner); I would use following patch to make sure bad things cant happen... Thanks diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 9e930c0..b8faf40 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); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo [at] vger More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|