Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+32 −30
Original line number Original line Diff line number Diff line
@@ -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)
		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)


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)
		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 = {
	.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,