summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2021-09-17 13:46:21 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-10-06 10:23:42 +0200
commitc0adb5a947dec6cff7050ec56d78ecd3916f9ce6 (patch)
tree5377499cf2faa65019de3cf53274b234f3df9219
parentf99060fd36a18ee64e47dced167f7173c06eb780 (diff)
downloadlinux-c0adb5a947dec6cff7050ec56d78ecd3916f9ce6.tar.gz
linux-c0adb5a947dec6cff7050ec56d78ecd3916f9ce6.tar.bz2
linux-c0adb5a947dec6cff7050ec56d78ecd3916f9ce6.zip
ipack: ipoctal: fix module reference leak
commit bb8a4fcb2136508224c596a7e665bdba1d7c3c27 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: 82a82340bab6 ("ipoctal: get carrier driver to avoid rmmod") Cc: stable@vger.kernel.org # 3.18 Cc: Federico Vaga <federico.vaga@cern.ch> Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://lore.kernel.org/r/20210917114622.5412-6-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/ipack/devices/ipoctal.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index 2765ab54b582..f558aeb8f888 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -87,22 +87,34 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
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 *ipoctal = chan_to_ipoctal(channel, tty->index);
- int err;
-
- tty->driver_data = channel;
+ int res;
if (!ipack_get_carrier(ipoctal->dev))
return -EBUSY;
- err = tty_port_open(&channel->tty_port, tty, file);
- if (err)
- ipack_put_carrier(ipoctal->dev);
+ res = tty_standard_install(driver, tty);
+ if (res)
+ 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)
@@ -668,6 +680,7 @@ static void ipoctal_cleanup(struct tty_struct *tty)
static const struct tty_operations ipoctal_fops = {
.ioctl = NULL,
+ .install = ipoctal_install,
.open = ipoctal_open,
.close = ipoctal_close,
.write = ipoctal_write_tty,