aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/n_tty.c
diff options
context:
space:
mode:
authorStanislav Kozina <skozina@redhat.com>2012-08-09 09:48:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 16:13:11 -0400
commit00aaae033e323af33740e7012a8ba4b0fa6dce20 (patch)
tree152d5cfb0186d2c4c5fadae2e79cf49d154be911 /drivers/tty/n_tty.c
parent857196e2758f01ec40f93429013963ca5f22cbae (diff)
tty: Fix possible race in n_tty_read()
Fix possible panic caused by unlocked access to tty->read_cnt in while-loop condition in n_tty_read(). Signed-off-by: Stanislav Kozina <skozina@redhat.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r--drivers/tty/n_tty.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 101790cea4ae..20de673a7730 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1838,13 +1838,13 @@ do_it_again:
1838 1838
1839 if (tty->icanon && !L_EXTPROC(tty)) { 1839 if (tty->icanon && !L_EXTPROC(tty)) {
1840 /* N.B. avoid overrun if nr == 0 */ 1840 /* N.B. avoid overrun if nr == 0 */
1841 spin_lock_irqsave(&tty->read_lock, flags);
1841 while (nr && tty->read_cnt) { 1842 while (nr && tty->read_cnt) {
1842 int eol; 1843 int eol;
1843 1844
1844 eol = test_and_clear_bit(tty->read_tail, 1845 eol = test_and_clear_bit(tty->read_tail,
1845 tty->read_flags); 1846 tty->read_flags);
1846 c = tty->read_buf[tty->read_tail]; 1847 c = tty->read_buf[tty->read_tail];
1847 spin_lock_irqsave(&tty->read_lock, flags);
1848 tty->read_tail = ((tty->read_tail+1) & 1848 tty->read_tail = ((tty->read_tail+1) &
1849 (N_TTY_BUF_SIZE-1)); 1849 (N_TTY_BUF_SIZE-1));
1850 tty->read_cnt--; 1850 tty->read_cnt--;
@@ -1862,15 +1862,19 @@ do_it_again:
1862 if (tty_put_user(tty, c, b++)) { 1862 if (tty_put_user(tty, c, b++)) {
1863 retval = -EFAULT; 1863 retval = -EFAULT;
1864 b--; 1864 b--;
1865 spin_lock_irqsave(&tty->read_lock, flags);
1865 break; 1866 break;
1866 } 1867 }
1867 nr--; 1868 nr--;
1868 } 1869 }
1869 if (eol) { 1870 if (eol) {
1870 tty_audit_push(tty); 1871 tty_audit_push(tty);
1872 spin_lock_irqsave(&tty->read_lock, flags);
1871 break; 1873 break;
1872 } 1874 }
1875 spin_lock_irqsave(&tty->read_lock, flags);
1873 } 1876 }
1877 spin_unlock_irqrestore(&tty->read_lock, flags);
1874 if (retval) 1878 if (retval)
1875 break; 1879 break;
1876 } else { 1880 } else {