aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-06-29 10:21:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-29 12:33:26 -0400
commitaef29bc2603014cb28dfe39bab8d888546fe18e7 (patch)
tree2fd190b9fb78504adbb7e1fdf902ad9f682633bc
parent52989765629e7d182b4f146050ebba0abf2cb0b7 (diff)
tty: Fix the leak in tty_ldisc_release
Currently we reinit the ldisc on final tty close which is what the old code did to ensure that if the device retained its termios settings then it had the right ldisc. tty_ldisc_reinit does that but also leaves us with the reset ldisc reference which is then leaked. At this point we know the port will be recycled so we can kill the ldisc off completely rather than try and add another ldisc free up when the kref count hits zero. At this point it is safe to keep the ldisc closed as tty_ldisc waiting methods are only used from the user side, and as the final close we are the last such reference. Interrupt/driver side methods will always use the non wait version and get back a NULL. Found with kmemleak and investigated/identified by Catalin Marinas. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/tty_ldisc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index a19e935847b0..913aa8d3f1c5 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -867,15 +867,22 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
867 tty_ldisc_wait_idle(tty); 867 tty_ldisc_wait_idle(tty);
868 868
869 /* 869 /*
870 * Shutdown the current line discipline, and reset it to N_TTY. 870 * Now kill off the ldisc
871 *
872 * FIXME: this MUST get fixed for the new reflocking
873 */ 871 */
872 tty_ldisc_close(tty, tty->ldisc);
873 tty_ldisc_put(tty->ldisc);
874 /* Force an oops if we mess this up */
875 tty->ldisc = NULL;
876
877 /* Ensure the next open requests the N_TTY ldisc */
878 tty_set_termios_ldisc(tty, N_TTY);
874 879
875 tty_ldisc_reinit(tty);
876 /* This will need doing differently if we need to lock */ 880 /* This will need doing differently if we need to lock */
877 if (o_tty) 881 if (o_tty)
878 tty_ldisc_release(o_tty, NULL); 882 tty_ldisc_release(o_tty, NULL);
883
884 /* And the memory resources remaining (buffers, termios) will be
885 disposed of when the kref hits zero */
879} 886}
880 887
881/** 888/**