Skip to content
Snippets Groups Projects
Commit dde4c142 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

ipack: ipoctal: fix module reference leak


commit bb8a4fcb upstream.

A reference to the carrier module was taken on every open but was only
released once when the final reference to the tty struct was dropped.

Fix this by taking the module reference and initialising the tty driver
data when installing the tty.

Fixes: 82a82340 ("ipoctal: get carrier driver to avoid rmmod")
Cc: stable@vger.kernel.org      # 3.18
Cc: Federico Vaga <federico.vaga@cern.ch>
Acked-by: default avatarSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20210917114622.5412-6-johan@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 58e818cd
No related branches found
No related tags found
No related merge requests found
...@@ -87,22 +87,34 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) ...@@ -87,22 +87,34 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
return 0; return 0;
} }
static int ipoctal_open(struct tty_struct *tty, struct file *file) static int ipoctal_install(struct tty_driver *driver, struct tty_struct *tty)
{ {
struct ipoctal_channel *channel = dev_get_drvdata(tty->dev); struct ipoctal_channel *channel = dev_get_drvdata(tty->dev);
struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
int err; int res;
tty->driver_data = channel;
if (!ipack_get_carrier(ipoctal->dev)) if (!ipack_get_carrier(ipoctal->dev))
return -EBUSY; return -EBUSY;
err = tty_port_open(&channel->tty_port, tty, file); res = tty_standard_install(driver, tty);
if (err) if (res)
ipack_put_carrier(ipoctal->dev); goto err_put_carrier;
tty->driver_data = channel;
return 0;
err_put_carrier:
ipack_put_carrier(ipoctal->dev);
return res;
}
static int ipoctal_open(struct tty_struct *tty, struct file *file)
{
struct ipoctal_channel *channel = tty->driver_data;
return err; return tty_port_open(&channel->tty_port, tty, file);
} }
static void ipoctal_reset_stats(struct ipoctal_stats *stats) static void ipoctal_reset_stats(struct ipoctal_stats *stats)
...@@ -668,6 +680,7 @@ static void ipoctal_cleanup(struct tty_struct *tty) ...@@ -668,6 +680,7 @@ static void ipoctal_cleanup(struct tty_struct *tty)
static const struct tty_operations ipoctal_fops = { static const struct tty_operations ipoctal_fops = {
.ioctl = NULL, .ioctl = NULL,
.install = ipoctal_install,
.open = ipoctal_open, .open = ipoctal_open,
.close = ipoctal_close, .close = ipoctal_close,
.write = ipoctal_write_tty, .write = ipoctal_write_tty,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment