Commit 4230af57 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

USB: mos7720: fix port-data memory leak

Fix port-data memory leak by moving port data allocation and
deallocation to port_probe and port_remove.

Since commit 0998d063 (device-core: Ensure drvdata = NULL when no
driver is bound) the port private data is no longer freed at release as
it is no longer accessible.

Note that this patch also fixes a second port-data memory leak in the
error path of attach, should parallel-port initialisation fail.

Compile-only tested.

Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fb44ff85
...@@ -1966,9 +1966,7 @@ static int mos7720_ioctl(struct tty_struct *tty, ...@@ -1966,9 +1966,7 @@ static int mos7720_ioctl(struct tty_struct *tty,
static int mos7720_startup(struct usb_serial *serial) static int mos7720_startup(struct usb_serial *serial)
{ {
struct moschip_port *mos7720_port;
struct usb_device *dev; struct usb_device *dev;
int i;
char data; char data;
u16 product; u16 product;
int ret_val; int ret_val;
...@@ -1999,29 +1997,6 @@ static int mos7720_startup(struct usb_serial *serial) ...@@ -1999,29 +1997,6 @@ static int mos7720_startup(struct usb_serial *serial)
serial->port[1]->interrupt_in_buffer = NULL; serial->port[1]->interrupt_in_buffer = NULL;
} }
/* set up serial port private structures */
for (i = 0; i < serial->num_ports; ++i) {
mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
if (mos7720_port == NULL) {
dev_err(&dev->dev, "%s - Out of memory\n", __func__);
return -ENOMEM;
}
/* Initialize all port interrupt end point to port 0 int
* endpoint. Our device has only one interrupt endpoint
* common to all ports */
serial->port[i]->interrupt_in_endpointAddress =
serial->port[0]->interrupt_in_endpointAddress;
mos7720_port->port = serial->port[i];
usb_set_serial_port_data(serial->port[i], mos7720_port);
dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number);
dev_dbg(&dev->dev, "serial number is %d\n", serial->minor);
}
/* setting configuration feature to one */ /* setting configuration feature to one */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
...@@ -2049,8 +2024,6 @@ static int mos7720_startup(struct usb_serial *serial) ...@@ -2049,8 +2024,6 @@ static int mos7720_startup(struct usb_serial *serial)
static void mos7720_release(struct usb_serial *serial) static void mos7720_release(struct usb_serial *serial)
{ {
int i;
#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
/* close the parallel port */ /* close the parallel port */
...@@ -2089,9 +2062,36 @@ static void mos7720_release(struct usb_serial *serial) ...@@ -2089,9 +2062,36 @@ static void mos7720_release(struct usb_serial *serial)
kref_put(&mos_parport->ref_count, destroy_mos_parport); kref_put(&mos_parport->ref_count, destroy_mos_parport);
} }
#endif #endif
/* free private structure allocated for serial port */ }
for (i = 0; i < serial->num_ports; ++i)
kfree(usb_get_serial_port_data(serial->port[i])); static int mos7720_port_probe(struct usb_serial_port *port)
{
struct moschip_port *mos7720_port;
mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL);
if (!mos7720_port)
return -ENOMEM;
/* Initialize all port interrupt end point to port 0 int endpoint.
* Our device has only one interrupt endpoint common to all ports.
*/
port->interrupt_in_endpointAddress =
port->serial->port[0]->interrupt_in_endpointAddress;
mos7720_port->port = port;
usb_set_serial_port_data(port, mos7720_port);
return 0;
}
static int mos7720_port_remove(struct usb_serial_port *port)
{
struct moschip_port *mos7720_port;
mos7720_port = usb_get_serial_port_data(port);
kfree(mos7720_port);
return 0;
} }
static struct usb_serial_driver moschip7720_2port_driver = { static struct usb_serial_driver moschip7720_2port_driver = {
...@@ -2109,6 +2109,8 @@ static struct usb_serial_driver moschip7720_2port_driver = { ...@@ -2109,6 +2109,8 @@ static struct usb_serial_driver moschip7720_2port_driver = {
.probe = mos77xx_probe, .probe = mos77xx_probe,
.attach = mos7720_startup, .attach = mos7720_startup,
.release = mos7720_release, .release = mos7720_release,
.port_probe = mos7720_port_probe,
.port_remove = mos7720_port_remove,
.ioctl = mos7720_ioctl, .ioctl = mos7720_ioctl,
.tiocmget = mos7720_tiocmget, .tiocmget = mos7720_tiocmget,
.tiocmset = mos7720_tiocmset, .tiocmset = mos7720_tiocmset,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment