]> git.hungrycats.org Git - linux/commitdiff
[PATCH] tty oops fix
authorAndrew Morton <akpm@osdl.org>
Sun, 31 Aug 2003 11:36:41 +0000 (04:36 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 31 Aug 2003 11:36:41 +0000 (04:36 -0700)
Ancient bug, reported by Hiroshi Inoue <inoueh@uranus.dti.ne.jp>:

 1. login to tty2 (not tty1)
 2. start kon (Kanji cONsole emulator, console which support
    Japanese characters)
 3. exit kon
 4. logout

It oopses in the debugging function check_tty_count(), walking a list_head
which has been list_del()'d.   Call trace is:

#0  check_tty_count (tty=0x10d42000, routine=0xc817b00 ".paths") at include/asm/processor.h:583
#1  0x022c6c00 in do_tty_hangup (data=0x10d42000) at drivers/char/tty_io.c:426
#2  0x022c6f60 in tty_vhangup (tty=0xc817b00) at drivers/char/tty_io.c:536
#3  0x022c6fcc in disassociate_ctty (on_exit=1) at drivers/char/tty_io.c:574
#4  0x02127aee in do_exit (code=0) at kernel/exit.c:718
#5  0x02127caa in do_group_exit (exit_code=0) at kernel/exit.c:796
#6  0x02127cbc in sys_exit_group (error_code=0) at kernel/exit.c:807

The tty refcount is zero, so everything seems consistent and sensible.  The
fix just uses list_del_init() on that list_head.

Heaven knows what the locking for tty->count is though.  Some bizarre mixture
of BKL, tty_sem and nothing at all.

drivers/char/tty_io.c

index d0e06f0e6bcf86b60a5c337093a9752617cf0fde..aab1780082fcd334ce4ec07d4732a6abce1f7aaf 100644 (file)
@@ -1023,7 +1023,7 @@ static void release_mem(struct tty_struct *tty, int idx)
                o_tty->magic = 0;
                o_tty->driver->refcount--;
                file_list_lock();
-               list_del(&o_tty->tty_files);
+               list_del_init(&o_tty->tty_files);
                file_list_unlock();
                free_tty_struct(o_tty);
        }
@@ -1037,7 +1037,7 @@ static void release_mem(struct tty_struct *tty, int idx)
        tty->magic = 0;
        tty->driver->refcount--;
        file_list_lock();
-       list_del(&tty->tty_files);
+       list_del_init(&tty->tty_files);
        file_list_unlock();
        module_put(tty->driver->owner);
        free_tty_struct(tty);