USB: ch341: fix port-data memory leak
authorJohan Hovold <jhovold@gmail.com>
Thu, 25 Oct 2012 08:29:03 +0000 (10:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Oct 2012 16:36:57 +0000 (09:36 -0700)
Fix port-data memory leak by moving port data allocation to port_probe
and actually implementing deallocation.

Note that this driver has never even bothered to try to deallocate it's
port data...

Compile-only tested.

Cc: <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/ch341.c

index e9c7046ae355a9da6746c83b669b8605c38fec96..d255f66e708e80ee78d72bc052bef4e71ba578e2 100644 (file)
@@ -242,13 +242,11 @@ out:      kfree(buffer);
        return r;
 }
 
-/* allocate private data */
-static int ch341_attach(struct usb_serial *serial)
+static int ch341_port_probe(struct usb_serial_port *port)
 {
        struct ch341_private *priv;
        int r;
 
-       /* private data */
        priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -258,17 +256,27 @@ static int ch341_attach(struct usb_serial *serial)
        priv->baud_rate = DEFAULT_BAUD_RATE;
        priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
 
-       r = ch341_configure(serial->dev, priv);
+       r = ch341_configure(port->serial->dev, priv);
        if (r < 0)
                goto error;
 
-       usb_set_serial_port_data(serial->port[0], priv);
+       usb_set_serial_port_data(port, priv);
        return 0;
 
 error: kfree(priv);
        return r;
 }
 
+static int ch341_port_remove(struct usb_serial_port *port)
+{
+       struct ch341_private *priv;
+
+       priv = usb_get_serial_port_data(port);
+       kfree(priv);
+
+       return 0;
+}
+
 static int ch341_carrier_raised(struct usb_serial_port *port)
 {
        struct ch341_private *priv = usb_get_serial_port_data(port);
@@ -304,7 +312,7 @@ static void ch341_close(struct usb_serial_port *port)
 static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
-       struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
+       struct ch341_private *priv = usb_get_serial_port_data(port);
        int r;
 
        priv->baud_rate = DEFAULT_BAUD_RATE;
@@ -608,7 +616,8 @@ static struct usb_serial_driver ch341_device = {
        .tiocmget          = ch341_tiocmget,
        .tiocmset          = ch341_tiocmset,
        .read_int_callback = ch341_read_int_callback,
-       .attach            = ch341_attach,
+       .port_probe        = ch341_port_probe,
+       .port_remove       = ch341_port_remove,
        .reset_resume      = ch341_reset_resume,
 };