Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8b710b3 authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

tty: Fix ldisc leak in failed tty_init_dev()



release_tty() leaks the ldisc instance when called directly (rather
than when releasing the file descriptor from tty_release()).

Since tty_ldisc_release() clears tty->ldisc, releasing the ldisc
instance at tty teardown if tty->ldisc is non-null is not in danger
of double-releasing the ldisc.

Remove deinitialize_tty_struct() now that free_tty_struct() always
performs the tty_ldisc_deinit().

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f4f9edcf
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
		   the easy way .. */
		retval = tty_init_termios(tty);
		if (retval)
			goto err_deinit_tty;
			goto err_free_tty;

		retval = tty_init_termios(o_tty);
		if (retval)
@@ -447,8 +447,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
err_free_termios:
	if (legacy)
		tty_free_termios(tty);
err_deinit_tty:
	deinitialize_tty_struct(o_tty);
err_free_tty:
	free_tty_struct(o_tty);
err_put_module:
	module_put(driver->other->owner);
+3 −17
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ void free_tty_struct(struct tty_struct *tty)
{
	if (!tty)
		return;
	tty_ldisc_deinit(tty);
	put_device(tty->dev);
	kfree(tty->write_buf);
	tty->magic = 0xDEADDEAD;
@@ -1529,7 +1530,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
	tty_lock(tty);
	retval = tty_driver_install_tty(driver, tty);
	if (retval < 0)
		goto err_deinit_tty;
		goto err_free_tty;

	if (!tty->port)
		tty->port = driver->ports[idx];
@@ -1551,9 +1552,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
	/* Return the tty locked so that it cannot vanish under the caller */
	return tty;

err_deinit_tty:
err_free_tty:
	tty_unlock(tty);
	deinitialize_tty_struct(tty);
	free_tty_struct(tty);
err_module_put:
	module_put(driver->owner);
@@ -3162,20 +3162,6 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
	return tty;
}

/**
 *	deinitialize_tty_struct
 *	@tty: tty to deinitialize
 *
 *	This subroutine deinitializes a tty structure that has been newly
 *	allocated but tty_release cannot be called on that yet.
 *
 *	Locking: none - tty in question must not be exposed at this point
 */
void deinitialize_tty_struct(struct tty_struct *tty)
{
	tty_ldisc_deinit(tty);
}

/**
 *	tty_put_char	-	write one character to a tty
 *	@tty: tty
+3 −2
Original line number Diff line number Diff line
@@ -797,7 +797,7 @@ void tty_ldisc_init(struct tty_struct *tty)
}

/**
 *	tty_ldisc_init		-	ldisc cleanup for new tty
 *	tty_ldisc_deinit	-	ldisc cleanup for new tty
 *	@tty: tty that was allocated recently
 *
 *	The tty structure must not becompletely set up (tty_ldisc_setup) when
@@ -805,6 +805,7 @@ void tty_ldisc_init(struct tty_struct *tty)
 */
void tty_ldisc_deinit(struct tty_struct *tty)
{
	if (tty->ldisc)
		tty_ldisc_put(tty->ldisc);
	tty->ldisc = NULL;
}
+0 −1
Original line number Diff line number Diff line
@@ -509,7 +509,6 @@ extern int tty_alloc_file(struct file *file);
extern void tty_add_file(struct tty_struct *tty, struct file *file);
extern void tty_free_file(struct file *file);
extern void free_tty_struct(struct tty_struct *tty);
extern void deinitialize_tty_struct(struct tty_struct *tty);
extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx);
extern int tty_release(struct inode *inode, struct file *filp);
extern int tty_init_termios(struct tty_struct *tty);