OS/RedHat Bug Report
[BUG] RHEL 6 machine crashes while trying to read from a tty
SYPER
2014. 4. 24. 15:18
RHEL 6 machine crashes while trying to read from a tty
Issue:
- kernel BUG at drivers/char/n_tty.c:1713!
- Kernel panic due to NULL pointer dereference at n_tty_read+0x2c9
- Red Hat Enterprise Linux 6.1
- kernel-2.6.32-131.0.15.el6
Fix to be included in upcoming RHEL 6.3 errata, and RHEL 6.4. See upstream patch submitted here.
Root Cause
In n_tty_read() the tty read_lock is taken AFTER reading the buffer:
1819 eol = test_and_clear_bit(tty->read_tail, 1820 tty->read_flags); 1821 c = tty->read_buf[tty->read_tail]; 1822 spin_lock_irqsave(&tty->read_lock, flags);In all other cases this lock is used for accessing the buffer, for example in reset_buffer_flags():
170 spin_lock_irqsave(&tty->read_lock, flags); 171 tty->read_head = tty->read_tail = tty->read_cnt = 0; 172 spin_unlock_irqrestore(&tty->read_lock, flags);This leads to a race condition:
CPU0 CPU1 n_tty_read: reset_buffer_flags: while (nr && tty->read_cnt) { spin_lock_irqsave(&tty->read_lock, flags); tty->read_head = tty->read_tail = tty->read_cnt = 0; spin_lock_irqsave(&tty->read_lock, flags); spin_lock_irqsave(&tty->read_lock, flags); tty->read_cnt--; spin_lock_irqsave(&tty->read_lock, flags); /* Now tty->read_cnt is negative */The tty device may be closed while reading from the read buffer. This causes the panics.