mxser: fix xmit_buf leak in activate when LSR == 0xff
authorJiri Slaby <jslaby@suse.cz>
Mon, 24 Jan 2022 07:14:24 +0000 (08:14 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Apr 2022 07:06:36 +0000 (09:06 +0200)
[ Upstream commit cd3a4907ee334b40d7aa880c7ab310b154fd5cd4 ]

When LSR is 0xff in ->activate() (rather unlike), we return an error.
Provided ->shutdown() is not called when ->activate() fails, nothing
actually frees the buffer in this case.

Fix this by properly freeing the buffer in a designated label. We jump
there also from the "!info->type" if now too.

Fixes: 6769140d3047 ("tty: mxser: use the tty_port_open method")
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Link: https://lore.kernel.org/r/20220124071430.14907-6-jslaby@suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/tty/mxser.c

index 69294ae154be0f17ae0e56c39d6fa048077b3c9c..ea7f4af85d58bfcc689ef6131f49a4c8e5a8d476 100644 (file)
@@ -860,6 +860,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
        struct mxser_port *info = container_of(port, struct mxser_port, port);
        unsigned long page;
        unsigned long flags;
+       int ret;
 
        page = __get_free_page(GFP_KERNEL);
        if (!page)
@@ -869,9 +870,9 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
 
        if (!info->ioaddr || !info->type) {
                set_bit(TTY_IO_ERROR, &tty->flags);
-               free_page(page);
                spin_unlock_irqrestore(&info->slock, flags);
-               return 0;
+               ret = 0;
+               goto err_free_xmit;
        }
        info->port.xmit_buf = (unsigned char *) page;
 
@@ -897,8 +898,10 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
                if (capable(CAP_SYS_ADMIN)) {
                        set_bit(TTY_IO_ERROR, &tty->flags);
                        return 0;
-               } else
-                       return -ENODEV;
+               }
+
+               ret = -ENODEV;
+               goto err_free_xmit;
        }
 
        /*
@@ -943,6 +946,10 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty)
        spin_unlock_irqrestore(&info->slock, flags);
 
        return 0;
+err_free_xmit:
+       free_page(page);
+       info->port.xmit_buf = NULL;
+       return ret;
 }
 
 /*