| From 7bdce71822f471433dd3014692e9096996c7b5f0 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <jhovold@gmail.com> |
| Date: Mon, 15 Oct 2012 18:20:52 +0200 |
| Subject: USB: ark3116: fix NULL-pointer dereference |
| |
| From: Johan Hovold <jhovold@gmail.com> |
| |
| commit 7bdce71822f471433dd3014692e9096996c7b5f0 upstream. |
| |
| Fix NULL-pointer dereference at release 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 NULL when release is called. |
| |
| Compile-only tested. |
| |
| Signed-off-by: Johan Hovold <jhovold@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/serial/ark3116.c | 26 ++++++++++++++------------ |
| 1 file changed, 14 insertions(+), 12 deletions(-) |
| |
| --- a/drivers/usb/serial/ark3116.c |
| +++ b/drivers/usb/serial/ark3116.c |
| @@ -126,9 +126,6 @@ static inline int calc_divisor(int bps) |
| |
| static int ark3116_attach(struct usb_serial *serial) |
| { |
| - struct usb_serial_port *port = serial->port[0]; |
| - struct ark3116_private *priv; |
| - |
| /* make sure we have our end-points */ |
| if ((serial->num_bulk_in == 0) || |
| (serial->num_bulk_out == 0) || |
| @@ -143,8 +140,15 @@ static int ark3116_attach(struct usb_ser |
| return -EINVAL; |
| } |
| |
| - priv = kzalloc(sizeof(struct ark3116_private), |
| - GFP_KERNEL); |
| + return 0; |
| +} |
| + |
| +static int ark3116_port_probe(struct usb_serial_port *port) |
| +{ |
| + struct usb_serial *serial = port->serial; |
| + struct ark3116_private *priv; |
| + |
| + priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| if (!priv) |
| return -ENOMEM; |
| |
| @@ -199,18 +203,15 @@ static int ark3116_attach(struct usb_ser |
| return 0; |
| } |
| |
| -static void ark3116_release(struct usb_serial *serial) |
| +static int ark3116_port_remove(struct usb_serial_port *port) |
| { |
| - struct usb_serial_port *port = serial->port[0]; |
| struct ark3116_private *priv = usb_get_serial_port_data(port); |
| |
| /* device is closed, so URBs and DMA should be down */ |
| - |
| - usb_set_serial_port_data(port, NULL); |
| - |
| mutex_destroy(&priv->hw_lock); |
| - |
| kfree(priv); |
| + |
| + return 0; |
| } |
| |
| static void ark3116_init_termios(struct tty_struct *tty) |
| @@ -725,7 +726,8 @@ static struct usb_serial_driver ark3116_ |
| .id_table = id_table, |
| .num_ports = 1, |
| .attach = ark3116_attach, |
| - .release = ark3116_release, |
| + .port_probe = ark3116_port_probe, |
| + .port_remove = ark3116_port_remove, |
| .set_termios = ark3116_set_termios, |
| .init_termios = ark3116_init_termios, |
| .ioctl = ark3116_ioctl, |