答复: [PATCH v2] usb: gadget: u_serial: check Null pointer in EP callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello linux community expert:

>> diff --git a/drivers/usb/gadget/function/u_serial.c 
>> b/drivers/usb/gadget/function/u_serial.c
>> index b394105e55d6..65637d53bf02
>> --- a/drivers/usb/gadget/function/u_serial.c
>> +++ b/drivers/usb/gadget/function/u_serial.c
>> @@ -454,6 +454,14 @@ static void gs_read_complete(struct usb_ep *ep, 
>> struct usb_request *req)  {
>>  	struct gs_port	*port = ep->driver_data;
>>  
>> +	/* When port is NULL, return to avoid panic. */
>> +	if (!port)
>> +		return;
>> +

>This doesn't protect the port from going to NULL right after the above the check. Since you mentioned gser_disconnect is making port to NULL, add the serial_port_lock to protect port (just like its done on gser_disconnect/suspend/resume). Something like this would do.
  OK, it is more reasonable to modify it as follows, I will modify it again.

>diff --git a/drivers/usb/gadget/function/u_serial.c
>b/drivers/usb/gadget/function/u_serial.c
>index f975dc03a190..a33f8cd871ac 100644
>--- a/drivers/usb/gadget/function/u_serial.c
>+++ b/drivers/usb/gadget/function/u_serial.c
>@@ -451,10 +451,21 @@ static void gs_rx_push(struct work_struct *work)

>static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) {
>-       struct gs_port  *port = ep->driver_data;
>+       struct gs_port  *port;
>+       unsigned long   flags;
>+
>+       spin_lock_irqsave(&serial_port_lock, flags);
>+       port = ep->driver_data;
>+
>+       if (!port) {
>+               spin_unlock_irqrestore(&serial_port_lock, flags);
>+               return;
>+       }

>-       /* Queue all received data until the tty layer is ready for it. */
>       spin_lock(&port->port_lock);
>+       spin_unlock(&serial_port_lock);
>+
>+       /* Queue all received data until the tty layer is ready for it. 
>+ */
>       list_add_tail(&req->list, &port->read_queue);
>       schedule_delayed_work(&port->push, 0);
>       spin_unlock(&port->port_lock);
>
>>  	/* Queue all received data until the tty layer is ready for it. */
>>  	spin_lock(&port->port_lock);
>>  	list_add_tail(&req->list, &port->read_queue); @@ -465,6 +473,14 @@ 
>> static void gs_write_complete(struct usb_ep *ep, struct usb_request 
>> *req)  {
>>  	struct gs_port	*port = ep->driver_data;
>>  
>> +   /* When port is NULL, return to avoid panic. */
>> +	if (!port)
>> +		return;
>> +
>>  	spin_lock(&port->port_lock);
>>  	list_add(&req->list, &port->write_pool);
>>  	port->write_started--;
>Same here also

Thanks




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux