lkml.org 
[lkml]   [2005]   [Nov]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RESEND 2/2] - usbserial: race-condition fix.
    On Tue, 22 Nov 2005 14:13:53 -0800
    Greg KH <gregkh@suse.de> wrote:

    | On Tue, Nov 22, 2005 at 07:59:26PM -0200, Luiz Fernando Capitulino wrote:
    | > @@ -60,6 +61,7 @@ struct usb_serial_port {
    | > struct usb_serial * serial;
    | > struct tty_struct * tty;
    | > spinlock_t lock;
    | > + struct semaphore sem;
    |
    | You forgot to document what this semaphore is used for.

    Here goes the second patch again, with the documentation now.

    As I said before, would be good to apply these two patches now, and I
    can cleanup the spinlock usage until next week.


    Fixes a race-condition in the access of the port structure, described
    in detail at: http://marc.theaimsgroup.com/?l=linux-kernel&m=113216151918308&w=2

    Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>

    drivers/usb/serial/usb-serial.c | 14 +++++++++++++-
    drivers/usb/serial/usb-serial.h | 4 ++++
    2 files changed, 17 insertions(+), 1 deletion(-)

    diff -Nparu -X /home/lcapitulino/kernels/dontdiff a/drivers/usb/serial/usb-serial.c a~/drivers/usb/serial/usb-serial.c
    --- a/drivers/usb/serial/usb-serial.c 2005-11-23 15:30:20.000000000 -0200
    +++ a~/drivers/usb/serial/usb-serial.c 2005-11-23 15:23:19.000000000 -0200
    @@ -30,6 +30,7 @@
    #include <linux/list.h>
    #include <linux/smp_lock.h>
    #include <asm/uaccess.h>
    +#include <asm/semaphore.h>
    #include <linux/usb.h>
    #include "usb-serial.h"
    #include "pl2303.h"
    @@ -190,6 +191,9 @@ static int serial_open (struct tty_struc
    port = serial->port[portNumber];
    if (!port)
    return -ENODEV;
    +
    + if (down_interruptible(&port->sem))
    + return -ERESTARTSYS;

    ++port->open_count;

    @@ -215,6 +219,7 @@ static int serial_open (struct tty_struc
    goto bailout_module_put;
    }

    + up(&port->sem);
    return 0;

    bailout_module_put:
    @@ -222,6 +227,7 @@ bailout_module_put:
    bailout_kref_put:
    kref_put(&serial->kref, destroy_serial);
    port->open_count = 0;
    + up(&port->sem);
    return retval;
    }

    @@ -234,8 +240,10 @@ static void serial_close(struct tty_stru

    dbg("%s - port %d", __FUNCTION__, port->number);

    + down(&port->sem);
    +
    if (port->open_count == 0)
    - return;
    + goto out;

    --port->open_count;
    if (port->open_count == 0) {
    @@ -253,6 +261,9 @@ static void serial_close(struct tty_stru
    }

    kref_put(&port->serial->kref, destroy_serial);
    +
    +out:
    + up(&port->sem);
    }

    static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
    @@ -774,6 +785,7 @@ int usb_serial_probe(struct usb_interfac
    port->number = i + serial->minor;
    port->serial = serial;
    spin_lock_init(&port->lock);
    + sema_init(&port->sem, 1);
    INIT_WORK(&port->work, usb_serial_port_softint, port);
    serial->port[i] = port;
    }
    diff -Nparu -X /home/lcapitulino/kernels/dontdiff a/drivers/usb/serial/usb-serial.h a~/drivers/usb/serial/usb-serial.h
    --- a/drivers/usb/serial/usb-serial.h 2005-11-23 15:30:20.000000000 -0200
    +++ a~/drivers/usb/serial/usb-serial.h 2005-11-23 15:23:59.000000000 -0200
    @@ -16,6 +16,7 @@

    #include <linux/config.h>
    #include <linux/kref.h>
    +#include <asm/semaphore.h>

    #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
    #define SERIAL_TTY_MINORS 255 /* loads of devices :) */
    @@ -30,6 +31,8 @@
    * @serial: pointer back to the struct usb_serial owner of this port.
    * @tty: pointer to the corresponding tty for this port.
    * @lock: spinlock to grab when updating portions of this structure.
    + * @sem: semaphore used to synchronize serial_open() and serial_close()
    + * access for this port.
    * @number: the number of the port (the minor number).
    * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
    * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
    @@ -60,6 +63,7 @@ struct usb_serial_port {
    struct usb_serial * serial;
    struct tty_struct * tty;
    spinlock_t lock;
    + struct semaphore sem;
    unsigned char number;

    unsigned char * interrupt_in_buffer;

    --
    Luiz Fernando N. Capitulino
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-11-23 18:49    [W:0.050 / U:0.304 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site