summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2007-08-10 13:01:05 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-11 15:47:41 -0700
commit42fd552e8647316757ded0176466c41d17934dcf (patch)
tree07b0f4ed1934c05c6495c62ba943ab90bde6be84 /include
parentf8a745942b1b7f052cb76bb8a893d12cb6329c84 (diff)
downloadlinux-3.10-42fd552e8647316757ded0176466c41d17934dcf.tar.gz
linux-3.10-42fd552e8647316757ded0176466c41d17934dcf.tar.bz2
linux-3.10-42fd552e8647316757ded0176466c41d17934dcf.zip
fix serial buffer memory leak
Patch c5c34d4862e18ef07c1276d233507f540fb5a532 (tty: flush flip buffer on ldisc input queue flush) introduces a race condition which can lead to memory leaks. The problem can be triggered when tcflush() is called when data are being pushed to the line discipline driver by flush_to_ldisc(). flush_to_ldisc() releases tty->buf.lock when calling the line discipline receive_buf function. At that poing tty_buffer_flush() kicks in and sets both tty->buf.head and tty->buf.tail to NULL. When flush_to_ldisc() finishes, it restores tty->buf.head but doesn't touch tty->buf.tail. This corrups the buffer queue, and the next call to tty_buffer_request_room() will allocate a new buffer and overwrite tty->buf.head. The previous buffer is then lost forever without being released. (Thanks to Laurent for the above text, for finding, disgnosing and reporting the bug) - Use tty->flags bits for the flush status. - Wait for the flag to clear again before returning - Fix the doc error noted - Fix flush of empty queue leaving stale flushpending [akpm@linux-foundation.org: cleanup] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Paul Fulghum <paulkf@microgate.com> Cc: Laurent Pinchart <laurentp@cse-semaphore.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/tty.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 691a1748d9d..6570719eafd 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -274,6 +274,8 @@ struct tty_struct {
#define TTY_PTY_LOCK 16 /* pty private */
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
#define TTY_HUPPED 18 /* Post driver->hangup() */
+#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
+#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))