]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Oct 2012 17:50:45 +0000 (10:50 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Oct 2012 17:50:45 +0000 (10:50 -0700)
added patches:
usb-io_edgeport-fix-port-data-memory-leak.patch

queue-3.6/series
queue-3.6/usb-io_edgeport-fix-port-data-memory-leak.patch [new file with mode: 0644]

index 711508b8b6273174c3fa335151c03565b75c0cbe..edaab8a37872df7a350a18937cfc847191910574 100644 (file)
@@ -38,3 +38,4 @@ usb-cp210x-fix-port-data-memory-leak.patch
 usb-spcp8x5-fix-port-data-memory-leak.patch
 usb-ti_usb_3410_5052-fix-port-data-memory-leak.patch
 usb-kl5kusb105-fix-port-data-memory-leak.patch
+usb-io_edgeport-fix-port-data-memory-leak.patch
diff --git a/queue-3.6/usb-io_edgeport-fix-port-data-memory-leak.patch b/queue-3.6/usb-io_edgeport-fix-port-data-memory-leak.patch
new file mode 100644 (file)
index 0000000..2df8b6b
--- /dev/null
@@ -0,0 +1,153 @@
+From c27f3efc56080a246f6ab7f57f0a6f56d256d769 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Wed, 17 Oct 2012 13:34:57 +0200
+Subject: USB: io_edgeport: fix port-data memory leak
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit c27f3efc56080a246f6ab7f57f0a6f56d256d769 upstream.
+
+Fix port-data memory leak by moving port data allocation and
+deallocation to port_probe and port_remove.
+
+Since commit 0998d0631001288 (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.
+
+Compile-only tested.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c |   54 ++++++++++++++++++++-------------------
+ drivers/usb/serial/io_tables.h   |    8 +++++
+ 2 files changed, 37 insertions(+), 25 deletions(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -228,6 +228,8 @@ static int  edge_get_icount(struct tty_s
+ static int  edge_startup(struct usb_serial *serial);
+ static void edge_disconnect(struct usb_serial *serial);
+ static void edge_release(struct usb_serial *serial);
++static int edge_port_probe(struct usb_serial_port *port);
++static int edge_port_remove(struct usb_serial_port *port);
+ #include "io_tables.h"        /* all of the devices that this driver supports */
+@@ -2921,9 +2923,8 @@ static void load_application_firmware(st
+ static int edge_startup(struct usb_serial *serial)
+ {
+       struct edgeport_serial *edge_serial;
+-      struct edgeport_port *edge_port;
+       struct usb_device *dev;
+-      int i, j;
++      int i;
+       int response;
+       bool interrupt_in_found;
+       bool bulk_in_found;
+@@ -3007,26 +3008,6 @@ static int edge_startup(struct usb_seria
+       /* we set up the pointers to the endpoints in the edge_open function,
+        * as the structures aren't created yet. */
+-      /* set up our port private structures */
+-      for (i = 0; i < serial->num_ports; ++i) {
+-              edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
+-              if (edge_port == NULL) {
+-                      dev_err(&serial->dev->dev, "%s - Out of memory\n",
+-                                                                 __func__);
+-                      for (j = 0; j < i; ++j) {
+-                              kfree(usb_get_serial_port_data(serial->port[j]));
+-                              usb_set_serial_port_data(serial->port[j],
+-                                                                      NULL);
+-                      }
+-                      usb_set_serial_data(serial, NULL);
+-                      kfree(edge_serial);
+-                      return -ENOMEM;
+-              }
+-              spin_lock_init(&edge_port->ep_lock);
+-              edge_port->port = serial->port[i];
+-              usb_set_serial_port_data(serial->port[i], edge_port);
+-      }
+-
+       response = 0;
+       if (edge_serial->is_epic) {
+@@ -3175,12 +3156,35 @@ static void edge_release(struct usb_seri
+       dbg("%s", __func__);
+-      for (i = 0; i < serial->num_ports; ++i)
+-              kfree(usb_get_serial_port_data(serial->port[i]));
+-
+       kfree(edge_serial);
+ }
++static int edge_port_probe(struct usb_serial_port *port)
++{
++      struct edgeport_port *edge_port;
++
++      edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
++      if (!edge_port)
++              return -ENOMEM;
++
++      spin_lock_init(&edge_port->ep_lock);
++      edge_port->port = port;
++
++      usb_set_serial_port_data(port, edge_port);
++
++      return 0;
++}
++
++static int edge_port_remove(struct usb_serial_port *port)
++{
++      struct edgeport_port *edge_port;
++
++      edge_port = usb_get_serial_port_data(port);
++      kfree(edge_port);
++
++      return 0;
++}
++
+ module_usb_serial_driver(serial_drivers, id_table_combined);
+ MODULE_AUTHOR(DRIVER_AUTHOR);
+--- a/drivers/usb/serial/io_tables.h
++++ b/drivers/usb/serial/io_tables.h
+@@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport
+       .attach                 = edge_startup,
+       .disconnect             = edge_disconnect,
+       .release                = edge_release,
++      .port_probe             = edge_port_probe,
++      .port_remove            = edge_port_remove,
+       .ioctl                  = edge_ioctl,
+       .set_termios            = edge_set_termios,
+       .tiocmget               = edge_tiocmget,
+@@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport
+       .attach                 = edge_startup,
+       .disconnect             = edge_disconnect,
+       .release                = edge_release,
++      .port_probe             = edge_port_probe,
++      .port_remove            = edge_port_remove,
+       .ioctl                  = edge_ioctl,
+       .set_termios            = edge_set_termios,
+       .tiocmget               = edge_tiocmget,
+@@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport
+       .attach                 = edge_startup,
+       .disconnect             = edge_disconnect,
+       .release                = edge_release,
++      .port_probe             = edge_port_probe,
++      .port_remove            = edge_port_remove,
+       .ioctl                  = edge_ioctl,
+       .set_termios            = edge_set_termios,
+       .tiocmget               = edge_tiocmget,
+@@ -197,6 +203,8 @@ static struct usb_serial_driver epic_dev
+       .attach                 = edge_startup,
+       .disconnect             = edge_disconnect,
+       .release                = edge_release,
++      .port_probe             = edge_port_probe,
++      .port_remove            = edge_port_remove,
+       .ioctl                  = edge_ioctl,
+       .set_termios            = edge_set_termios,
+       .tiocmget               = edge_tiocmget,