From: Greg Kroah-Hartman Date: Wed, 24 Oct 2012 16:59:30 +0000 (-0700) Subject: 3.6-stable patches X-Git-Tag: v3.0.49~48 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=06cb43928d0fd49d2987ac981080590ecc846ef8;p=thirdparty%2Fkernel%2Fstable-queue.git 3.6-stable patches added patches: usb-cyberjack-fix-port-data-memory-leak.patch usb-io_ti-fix-sysfs-attribute-creation.patch --- diff --git a/queue-3.6/series b/queue-3.6/series index 8d5fd263070..d24a53fdae2 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -20,3 +20,5 @@ xen-x86-don-t-corrupt-eip-when-returning-from-a-signal-handler.patch usb-cdc-acm-fix-pipe-type-of-write-endpoint.patch usb-acm-fix-the-computation-of-the-number-of-data-bits.patch usb-io_ti-fix-port-data-memory-leak.patch +usb-io_ti-fix-sysfs-attribute-creation.patch +usb-cyberjack-fix-port-data-memory-leak.patch diff --git a/queue-3.6/usb-cyberjack-fix-port-data-memory-leak.patch b/queue-3.6/usb-cyberjack-fix-port-data-memory-leak.patch new file mode 100644 index 00000000000..9a9e21712be --- /dev/null +++ b/queue-3.6/usb-cyberjack-fix-port-data-memory-leak.patch @@ -0,0 +1,124 @@ +From a9556040119a63d06fd5238d47f5b683fba4178b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 15 Oct 2012 18:20:54 +0200 +Subject: USB: cyberjack: fix port-data memory leak + +From: Johan Hovold + +commit a9556040119a63d06fd5238d47f5b683fba4178b upstream. + +Fix port-data memory leak by replacing attach and release with +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. + +Note that the write waitqueue was initialised but never used. + +Compile-only tested. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cyberjack.c | 48 ++++++++++++++++------------------------- + 1 file changed, 19 insertions(+), 29 deletions(-) + +--- a/drivers/usb/serial/cyberjack.c ++++ b/drivers/usb/serial/cyberjack.c +@@ -57,9 +57,9 @@ static bool debug; + #define CYBERJACK_PRODUCT_ID 0x0100 + + /* Function prototypes */ +-static int cyberjack_startup(struct usb_serial *serial); + static void cyberjack_disconnect(struct usb_serial *serial); +-static void cyberjack_release(struct usb_serial *serial); ++static int cyberjack_port_probe(struct usb_serial_port *port); ++static int cyberjack_port_remove(struct usb_serial_port *port); + static int cyberjack_open(struct tty_struct *tty, + struct usb_serial_port *port); + static void cyberjack_close(struct usb_serial_port *port); +@@ -85,9 +85,9 @@ static struct usb_serial_driver cyberjac + .description = "Reiner SCT Cyberjack USB card reader", + .id_table = id_table, + .num_ports = 1, +- .attach = cyberjack_startup, + .disconnect = cyberjack_disconnect, +- .release = cyberjack_release, ++ .port_probe = cyberjack_port_probe, ++ .port_remove = cyberjack_port_remove, + .open = cyberjack_open, + .close = cyberjack_close, + .write = cyberjack_write, +@@ -109,55 +109,45 @@ struct cyberjack_private { + short wrsent; /* Data already sent */ + }; + +-/* do some startup allocations not currently performed by usb_serial_probe() */ +-static int cyberjack_startup(struct usb_serial *serial) ++static int cyberjack_port_probe(struct usb_serial_port *port) + { + struct cyberjack_private *priv; +- int i; ++ int result; + +- /* allocate the private data structure */ + priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; + +- /* set initial values */ + spin_lock_init(&priv->lock); + priv->rdtodo = 0; + priv->wrfilled = 0; + priv->wrsent = 0; +- usb_set_serial_port_data(serial->port[0], priv); + +- init_waitqueue_head(&serial->port[0]->write_wait); ++ usb_set_serial_port_data(port, priv); + +- for (i = 0; i < serial->num_ports; ++i) { +- int result; +- result = usb_submit_urb(serial->port[i]->interrupt_in_urb, +- GFP_KERNEL); +- if (result) +- dev_err(&serial->dev->dev, +- "usb_submit_urb(read int) failed\n"); +- dbg("%s - usb_submit_urb(int urb)", __func__); +- } ++ result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); ++ if (result) ++ dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); + + return 0; + } + +-static void cyberjack_disconnect(struct usb_serial *serial) ++static int cyberjack_port_remove(struct usb_serial_port *port) + { +- int i; ++ struct cyberjack_private *priv; + +- for (i = 0; i < serial->num_ports; ++i) +- usb_kill_urb(serial->port[i]->interrupt_in_urb); ++ priv = usb_get_serial_port_data(port); ++ kfree(priv); ++ ++ return 0; + } + +-static void cyberjack_release(struct usb_serial *serial) ++static void cyberjack_disconnect(struct usb_serial *serial) + { + int i; + +- for (i = 0; i < serial->num_ports; ++i) { +- /* My special items, the standard routines free my urbs */ +- kfree(usb_get_serial_port_data(serial->port[i])); +- } ++ for (i = 0; i < serial->num_ports; ++i) ++ usb_kill_urb(serial->port[i]->interrupt_in_urb); + } + + static int cyberjack_open(struct tty_struct *tty, diff --git a/queue-3.6/usb-io_ti-fix-sysfs-attribute-creation.patch b/queue-3.6/usb-io_ti-fix-sysfs-attribute-creation.patch new file mode 100644 index 00000000000..9fae4934547 --- /dev/null +++ b/queue-3.6/usb-io_ti-fix-sysfs-attribute-creation.patch @@ -0,0 +1,52 @@ +From 5d8c61bc283826827e1f06816c146bfc507d3834 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 18 Oct 2012 11:43:28 +0200 +Subject: USB: io_ti: fix sysfs-attribute creation + +From: Johan Hovold + +commit 5d8c61bc283826827e1f06816c146bfc507d3834 upstream. + +Make sure port data is initialised before creating sysfs attributes to +avoid a race. + +A recent patch ("USB: io_ti: fix port-data memory leak") got the +sysfs-attribute creation and port-data initialisation ordering wrong. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_ti.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -2641,13 +2641,6 @@ static int edge_port_probe(struct usb_se + return -ENOMEM; + } + +- ret = edge_create_sysfs_attrs(port); +- if (ret) { +- kfifo_free(&edge_port->write_fifo); +- kfree(edge_port); +- return ret; +- } +- + spin_lock_init(&edge_port->ep_lock); + edge_port->port = port; + edge_port->edge_serial = usb_get_serial_data(port->serial); +@@ -2655,6 +2648,13 @@ static int edge_port_probe(struct usb_se + + usb_set_serial_port_data(port, edge_port); + ++ ret = edge_create_sysfs_attrs(port); ++ if (ret) { ++ kfifo_free(&edge_port->write_fifo); ++ kfree(edge_port); ++ return ret; ++ } ++ + return 0; + } +