usb: gadget: u_serial: Add null pointer check in gs_start_io
authorKuen-Han Tsai <khtsai@google.com>
Fri, 2 Jun 2023 07:00:06 +0000 (15:00 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Jun 2023 09:55:09 +0000 (11:55 +0200)
If gs_close has cleared port->port.tty and gs_start_io is called
afterwards, then the function tty_wakeup will attempt to access the value
of the pointer port->port.tty which will cause a null pointer
dereference error.

To avoid this, add a null pointer check to gs_start_io before attempting
to access the value of the pointer port->port.tty.

Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Message-ID: <20230602070009.1353946-1-khtsai@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/u_serial.c

index 97f0775..1115396 100644 (file)
@@ -539,16 +539,20 @@ static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head,
 static int gs_start_io(struct gs_port *port)
 {
        struct list_head        *head = &port->read_pool;
-       struct usb_ep           *ep = port->port_usb->out;
+       struct usb_ep           *ep;
        int                     status;
        unsigned                started;
 
+       if (!port->port_usb || !port->port.tty)
+               return -EIO;
+
        /* Allocate RX and TX I/O buffers.  We can't easily do this much
         * earlier (with GFP_KERNEL) because the requests are coupled to
         * endpoints, as are the packet sizes we'll be using.  Different
         * configurations may use different endpoints with a given port;
         * and high speed vs full speed changes packet sizes too.
         */
+       ep = port->port_usb->out;
        status = gs_alloc_requests(ep, head, gs_read_complete,
                &port->read_allocated);
        if (status)