There still is a race window after the commit b027e2298bd588 ("tty: fix data race between tty_init_dev and flush of buf"), and we encountered this crash issue if receive_buf call comes before tty initialization completes in n_tty_open and tty->driver_data may be NULL.
CPU0 CPU1 ---- ---- n_tty_open tty_init_dev tty_ldisc_unlock schedule flush_to_ldisc receive_buf tty_port_default_receive_buf tty_ldisc_receive_buf n_tty_receive_buf_common __receive_buf uart_flush_chars uart_start /*tty->driver_data is NULL*/ tty->ops->open /*init tty->driver_data*/ it can be fixed by extending ldisc semaphore lock in tty_init_dev to driver_data initialized completely after tty->ops->open(), but this will lead to put lock on one function and unlock in some other function, and hard to maintain, so fix this race only by checking tty->driver_data when receiving, and return if tty->driver_data is NULL Signed-off-by: Wang Li <wangl...@baidu.com> Signed-off-by: Zhang Yu <zhangy...@baidu.com> Signed-off-by: Li RongQing <lirongq...@baidu.com> --- drivers/tty/tty_port.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 044c3cbdcfa4..86d0bec38322 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -31,6 +31,9 @@ static int tty_port_default_receive_buf(struct tty_port *port, if (!tty) return 0; + if (!tty->driver_data) + return 0; + disc = tty_ldisc_ref(tty); if (!disc) return 0; -- 2.16.2