lkml.org 
[lkml]   [2009]   [Apr]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: BUG: NULL pointer dereference in try_to_del_timer_sync()
    On Wed, 29 Apr 2009, Alan Stern wrote:

    > Looks like the ftdi_sio driver doesn't use proper reference counting
    > for its private data structure. Does this patch help?

    Oops, I forgot to initialize the kref. Try this patch instead.

    Alan Stern



    Index: 2.6.30-rc3/drivers/usb/serial/ftdi_sio.c
    ===================================================================
    --- 2.6.30-rc3.orig/drivers/usb/serial/ftdi_sio.c
    +++ 2.6.30-rc3/drivers/usb/serial/ftdi_sio.c
    @@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID;
    static __u16 product;

    struct ftdi_private {
    + struct kref kref;
    ftdi_chip_type_t chip_type;
    /* type of device, either SIO or FT8U232AM */
    int baud_base; /* baud base clock for divisor setting */
    @@ -1352,6 +1353,7 @@ static int ftdi_sio_port_probe(struct us
    return -ENOMEM;
    }

    + kref_init(&priv->kref);
    spin_lock_init(&priv->rx_lock);
    spin_lock_init(&priv->tx_lock);
    init_waitqueue_head(&priv->delta_msr_wait);
    @@ -1468,6 +1470,13 @@ static void ftdi_shutdown(struct usb_ser
    dbg("%s", __func__);
    }

    +static void ftdi_sio_priv_release(struct kref *k)
    +{
    + struct ftdi_private *priv = container_of(k, struct ftdi_private, kref);
    +
    + kfree(priv);
    +}
    +
    static int ftdi_sio_port_remove(struct usb_serial_port *port)
    {
    struct ftdi_private *priv = usb_get_serial_port_data(port);
    @@ -1482,7 +1491,7 @@ static int ftdi_sio_port_remove(struct u

    if (priv) {
    usb_set_serial_port_data(port, NULL);
    - kfree(priv);
    + kref_put(&priv->kref, ftdi_sio_priv_release);
    }

    return 0;
    @@ -1547,7 +1556,8 @@ static int ftdi_open(struct tty_struct *
    dev_err(&port->dev,
    "%s - failed submitting read urb, error %d\n",
    __func__, result);
    -
    + else
    + kref_get(&priv->kref);

    return result;
    } /* ftdi_open */
    @@ -1589,11 +1599,11 @@ static void ftdi_close(struct tty_struct
    mutex_unlock(&port->serial->disc_mutex);

    /* cancel any scheduled reading */
    - cancel_delayed_work(&priv->rx_work);
    - flush_scheduled_work();
    + cancel_delayed_work_sync(&priv->rx_work);

    /* shutdown our bulk read */
    usb_kill_urb(port->read_urb);
    + kref_put(&priv->kref, ftdi_sio_priv_release);
    } /* ftdi_close */




    \
     
     \ /
      Last update: 2009-04-29 18:05    [W:0.036 / U:121.248 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site