Skip to content

Commit

Permalink
USB: mct_u232: fix port-data memory leak
Browse files Browse the repository at this point in the history
Fix port-data memory leak by moving port data allocation and
deallocation to port_probe and port_remove.

Since commit 0998d06 (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 the write waitqueue was initialised but never used.

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>
  • Loading branch information
Johan Hovold authored and Greg Kroah-Hartman committed Oct 25, 2012
1 parent acbf0e5 commit a8f2ae7
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions drivers/usb/serial/mct_u232.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
* Function prototypes
*/
static int mct_u232_startup(struct usb_serial *serial);
static void mct_u232_release(struct usb_serial *serial);
static int mct_u232_port_probe(struct usb_serial_port *port);
static int mct_u232_port_remove(struct usb_serial_port *remove);
static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
static void mct_u232_close(struct usb_serial_port *port);
static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
Expand Down Expand Up @@ -99,7 +100,8 @@ static struct usb_serial_driver mct_u232_device = {
.tiocmget = mct_u232_tiocmget,
.tiocmset = mct_u232_tiocmset,
.attach = mct_u232_startup,
.release = mct_u232_release,
.port_probe = mct_u232_port_probe,
.port_remove = mct_u232_port_remove,
.ioctl = mct_u232_ioctl,
.get_icount = mct_u232_get_icount,
};
Expand Down Expand Up @@ -388,18 +390,8 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port,

static int mct_u232_startup(struct usb_serial *serial)
{
struct mct_u232_private *priv;
struct usb_serial_port *port, *rport;

priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->msr_wait);
usb_set_serial_port_data(serial->port[0], priv);

init_waitqueue_head(&serial->port[0]->write_wait);

/* Puh, that's dirty */
port = serial->port[0];
rport = serial->port[1];
Expand All @@ -412,18 +404,31 @@ static int mct_u232_startup(struct usb_serial *serial)
return 0;
} /* mct_u232_startup */

static int mct_u232_port_probe(struct usb_serial_port *port)
{
struct mct_u232_private *priv;

priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

static void mct_u232_release(struct usb_serial *serial)
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->msr_wait);

usb_set_serial_port_data(port, priv);

return 0;
}

static int mct_u232_port_remove(struct usb_serial_port *port)
{
struct mct_u232_private *priv;
int i;

for (i = 0; i < serial->num_ports; ++i) {
/* My special items, the standard routines free my urbs */
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
}
} /* mct_u232_release */
priv = usb_get_serial_port_data(port);
kfree(priv);

return 0;
}

static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
{
Expand Down

0 comments on commit a8f2ae7

Please sign in to comment.