Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: fix __tty_insert_flip_char regression

Sergey noticed a small but fatal mistake in __tty_insert_flip_char,
leading to an oops in an interrupt handler when using any serial
port.

The problem is that I accidentally took the tty_buffer pointer
before calling __tty_buffer_request_room(), which replaces the
buffer. This moves the pointer lookup to the right place after
allocating the new buffer space.

Fixes: 979990c62848 ("tty: improve tty_insert_flip_char() fast path")
Reported-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Tested-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Arnd Bergmann and committed by
Greg Kroah-Hartman
8a5a90a2 065ea0a7

+2 -1
+2 -1
drivers/tty/tty_buffer.c
··· 372 372 */ 373 373 int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) 374 374 { 375 - struct tty_buffer *tb = port->buf.tail; 375 + struct tty_buffer *tb; 376 376 int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; 377 377 378 378 if (!__tty_buffer_request_room(port, 1, flags)) 379 379 return 0; 380 380 381 + tb = port->buf.tail; 381 382 if (~tb->flags & TTYB_NORMAL) 382 383 *flag_buf_ptr(tb, tb->used) = flag; 383 384 *char_buf_ptr(tb, tb->used++) = ch;