[ 043/101] USB: ch341: fix port-data memory leak

From: Greg Kroah-Hartman
Date: Mon Oct 29 2012 - 18:11:48 EST


3.6-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <jhovold@xxxxxxxxx>

commit 456c5be56ed070a4d883c60b587bcc1c97a8cf3e upstream.

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.

Signed-off-by: Johan Hovold <jhovold@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/usb/serial/ch341.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)

--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -241,13 +241,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;
@@ -257,17 +255,27 @@ static int ch341_attach(struct usb_seria
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);
@@ -303,7 +311,7 @@ static void ch341_close(struct usb_seria
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;
@@ -606,7 +614,8 @@ static struct usb_serial_driver ch341_de
.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,
};



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/