Technical Root Cause Analysis
Involved Components
- File:
drivers/usb/serial/mct_u232.c
- Function:
mct_u232_open()
- Structs & Fields:
struct usb_serial_port: port->read_urb
struct mct_u232_private: priv->read_urb
struct urb: urb->pipe (located at offset 0x50 / byte 80)
Bug Mechanism
In the USB serial subsystem (drivers/usb/serial/usb-serial.c), port->read_urb is reserved for bulk-IN transfers and is only allocated and initialized by setup_port_bulk_in() when a port has bulk-IN endpoints.
The MCT U232 USB-to-RS232 adapter does not use bulk-IN endpoints for data transfer. Instead, it uses two interrupt-IN endpoints:
port->interrupt_in_urb (used for modem/line status notifications)
serial->port[1]->interrupt_in_urb (used for data reception)
During port initialization in mct_u232_port_probe(), the driver allocates its private context (struct mct_u232_private *priv) and assigns the second interrupt-IN URB to priv->read_urb:
priv->read_urb = serial->port[1]->interrupt_in_urb;
priv->read_urb->context = port;
Because no bulk-IN endpoints exist for the port, setup_port_bulk_in() is never called, leaving port->read_urb == NULL.
When opening the serial port in mct_u232_open(), the driver submits priv->read_urb:
retval = usb_submit_urb(priv->read_urb, GFP_KERNEL);
if (retval) {
dev_err(&port->dev,
"usb_submit_urb(read) failed pipe 0x%x err %d\n",
port->read_urb->pipe, retval);
goto error;
}
If usb_submit_urb(priv->read_urb, GFP_KERNEL) fails (e.g. if communication with the device fails or the device is disconnected), control enters the error block. When formatting the error log, the code mistakenly references port->read_urb->pipe instead of priv->read_urb->pipe.
Because port->read_urb is NULL, evaluating port->read_urb->pipe attempts to read 4 bytes at offset 0x50 (offset of pipe in struct urb). In KASAN-enabled kernels, checking the shadow memory for range [0x0000000000000050-0x0000000000000057] (address 0xdffffc000000000a) triggers a KASAN null-ptr-deref / general protection fault. In standard kernels, this triggers an immediate NULL pointer dereference page fault (unable to handle kernel paging request at 0000000000000050).