When removing a serial port driver (tested on 8250) while reading from one of the serial ports, the system will crash. This happens when the program closes the port. Using the following test program: #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char **argv) { int fd; fd = open( "/dev/ttyS0", O_RDONLY); sleep(10); close(fd); return 0; } If this program is running and the 8250 kernel driver is removed using 'rmmod', the system will panic with the following error: BUG: unable to handle kernel paging request at f2a82b3f IP: [<c11f9d0a>] strchr+0xa/0x20 Oops: 0000 [#1] PREEMPT SMP CPU: 4 PID: 873 Comm: kworker/4:2 Tainted: P O 4.4.11 #2 Workqueue: events release_one_tty Call Trace: [<c115548d>] __xlate_proc_name+0x4d/0xa0 [<c1155e88>] remove_proc_entry+0x28/0x150 [<c1069912>] ? put_prev_entity+0x22/0x950 [<c115836b>] proc_tty_unregister_driver+0x1b/0x30 [<c126faeb>] destruct_tty_driver+0x6b/0xc0 [<c126fb5a>] tty_driver_kref_put+0x1a/0x20 [<c126fd52>] release_one_tty+0x42/0x90 [<c105497e>] process_one_work+0xee/0x2b0 [<c1054c2d>] worker_thread+0xed/0x410 [<c1054b40>] ? process_one_work+0x2b0/0x2b0 [<c105953c>] kthread+0x9c/0xb0 [<c139ae98>] ? _raw_spin_unlock_irq+0x8/0x20 [<c139b389>] ret_from_kernel_thread+0x21/0x38 [<c10594a0>] ? kthread_create_on_node+0x120/0x120 The reason is that __xlate_proc_name() calls strchr() on a pointer to (struct tty_driver*)->name which is passed to it from proc_tty_unregister_driver() via remove_proc_entry(). The problem is caused by drivers (such as the 8250) having a static struct uart_driver ... which is removed from memory when rmmod is called. The .driver_name member of this structure is passed on to the struct tty_driver in drivers/tty/serial/serial_core: uart_register_driver() The problem can be avoided by having a modules' reference counter incremented when devices start using the serial port. This functionality is present in the tty core, but not used because the .owner parameter is not assigned when the tty_driver struct is allocated. We have been able to reproduce this problem on 3.10.34, 3.10.49 and 4.4.11. Signed-off-by: Michel Stam <m.stam@xxxxxxxxx> Signed-off-by: Tjalling Hattink <t.hattink@xxxxxxxxx> --- drivers/tty/serial/serial_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index def5199..323e800 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2413,6 +2413,7 @@ int uart_register_driver(struct uart_driver *drv) drv->tty_driver = normal; + normal->owner = drv->owner; normal->driver_name = drv->driver_name; normal->name = drv->dev_name; normal->major = drv->major; -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html