On Thu, Mar 13, 2025 at 09:58:50PM +0100, Elodie Decerle wrote: > When two instances of uart devices are probing, a concurrency race can > occur. > > If one thread calls uart_register_driver function, which first > allocates and assigns memory to 'uart_state' member of uart_driver > structure, the other instance can bypass uart driver registration and > call ulite_assign. This calls uart_add_one_port, which expects the uart > driver to be fully initialized. This leads to a kernel panic due to a > null pointer dereference: > > [ 8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8 > [ 8.156982] #PF: supervisor write access in kernel mode > [ 8.156984] #PF: error_code(0x0002) - not-present page > [ 8.156986] PGD 0 P4D 0 > ... > [ 8.180668] RIP: 0010:mutex_lock+0x19/0x30 > [ 8.188624] Call Trace: > [ 8.188629] ? __die_body.cold+0x1a/0x1f > [ 8.195260] ? page_fault_oops+0x15c/0x290 > [ 8.209183] ? __irq_resolve_mapping+0x47/0x80 > [ 8.209187] ? exc_page_fault+0x64/0x140 > [ 8.209190] ? asm_exc_page_fault+0x22/0x30 > [ 8.209196] ? mutex_lock+0x19/0x30 > [ 8.223116] uart_add_one_port+0x60/0x440 > [ 8.223122] ? proc_tty_register_driver+0x43/0x50 > [ 8.223126] ? tty_register_driver+0x1ca/0x1e0 > [ 8.246250] ulite_probe+0x357/0x4b0 [uartlite] > > Adding a mutex lock around the uart_register_driver call in the probe > function prevents this race condition and ensures that the uart driver > structure is fully initialized and registered before it is used. > > Signed-off-by: Elodie Decerle <elodie.decerle@xxxxxxxxx> > Reviewed-by: Jakub Lewalski <jakub.lewalski@xxxxxxxxx> > --- > drivers/tty/serial/uartlite.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c > index a41e7fc373b7..460eb2032efa 100644 > --- a/drivers/tty/serial/uartlite.c > +++ b/drivers/tty/serial/uartlite.c > @@ -23,6 +23,8 @@ > #include <linux/clk.h> > #include <linux/pm_runtime.h> > > +static DEFINE_MUTEX(uart_driver_register_lock); > + > #define ULITE_NAME "ttyUL" > #if CONFIG_SERIAL_UARTLITE_NR_UARTS > 4 > #define ULITE_MAJOR 0 /* use dynamic node allocation */ > @@ -880,6 +882,8 @@ static int ulite_probe(struct platform_device *pdev) > pm_runtime_set_active(&pdev->dev); > pm_runtime_enable(&pdev->dev); > > + mutex_lock(&uart_driver_register_lock); > + > if (!ulite_uart_driver.state) { So the problem that there is a single "state" for the driver as a whole. That should be fixed up to be local to each individual device that is added to the system. Don't add a lock to paper over this as odds are this is not the only place that will have problems. Are you just now having 2 of these devices in your system at the same time? thanks, greg k-h