public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to accessing null pointer
@ 2025-06-25 15:22 Dan Carpenter
  2025-06-26  2:16 ` 答复: " 胡连勤
  2025-06-26  6:22 ` Prashanth K
  0 siblings, 2 replies; 3+ messages in thread
From: Dan Carpenter @ 2025-06-25 15:22 UTC (permalink / raw)
  To: hulianqin; +Cc: linux-usb

Hello Lianqin Hu,

The patch 4cfbca86f6a8: "usb: gadget: u_serial: Fix the issue that
gs_start_io crashed due to accessing null pointer" from Dec 3, 2024,
leads to the following static checker warning:

	drivers/usb/gadget/function/u_serial.c:580 gs_start_io()
	warn: variable dereferenced before check 'port->port_usb' (see line 547)

drivers/usb/gadget/function/u_serial.c
    544 static int gs_start_io(struct gs_port *port)
    545 {
    546 	struct list_head	*head = &port->read_pool;
    547 	struct usb_ep		*ep = port->port_usb->out;
                                              ^^^^^^^^^^^^^^^^^^^
port->port_usb dereferenced here

    548 	int			status;
    549 	unsigned		started;
    550 
    551 	/* Allocate RX and TX I/O buffers.  We can't easily do this much
    552 	 * earlier (with GFP_KERNEL) because the requests are coupled to
    553 	 * endpoints, as are the packet sizes we'll be using.  Different
    554 	 * configurations may use different endpoints with a given port;
    555 	 * and high speed vs full speed changes packet sizes too.
    556 	 */
    557 	status = gs_alloc_requests(ep, head, gs_read_complete,
    558 		&port->read_allocated);
    559 	if (status)
    560 		return status;
    561 
    562 	status = gs_alloc_requests(port->port_usb->in, &port->write_pool,
                                           ^^^^^^^^^^^^^^^^^^
and here

    563 			gs_write_complete, &port->write_allocated);
    564 	if (status) {
    565 		gs_free_requests(ep, head, &port->read_allocated);
    566 		return status;
    567 	}
    568 
    569 	/* queue read requests */
    570 	port->n_read = 0;
    571 	started = gs_start_rx(port);
    572 
    573 	if (started) {
    574 		gs_start_tx(port);
    575 		/* Unblock any pending writes into our circular buffer, in case
    576 		 * we didn't in gs_start_tx() */
    577 		tty_port_tty_wakeup(&port->port);
    578 	} else {
    579 		/* Free reqs only if we are still connected */
--> 580 		if (port->port_usb) {
                            ^^^^^^^^^^^^^^
Checked here.  The commit message says that this is to fix a race
condition where a different thread could set port->port_usb to NULL
after we call gs_start_rx().  However, the code is still racy
because we're not holding the spin_lock(&port->port_lock) so port->usb
could still be freed between lines 580 and 582.  The window for the
race is much smaller but it's still a potential issue.

    581 			gs_free_requests(ep, head, &port->read_allocated);
    582 			gs_free_requests(port->port_usb->in, &port->write_pool,
    583 				&port->write_allocated);
    584 		}
    585 		status = -EIO;
    586 	}
    587 
    588 	return status;
    589 }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-06-26  6:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-25 15:22 [bug report] usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to accessing null pointer Dan Carpenter
2025-06-26  2:16 ` 答复: " 胡连勤
2025-06-26  6:22 ` Prashanth K

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox