]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.10.72/tty-fix-tty_wait_until_sent-on-64-bit-machines.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.72 / tty-fix-tty_wait_until_sent-on-64-bit-machines.patch
CommitLineData
9bdf00d0
GKH
1From 79fbf4a550ed6a22e1ae1516113e6c7fa5d56a53 Mon Sep 17 00:00:00 2001
2From: Johan Hovold <johan@kernel.org>
3Date: Wed, 4 Mar 2015 10:39:06 +0100
4Subject: TTY: fix tty_wait_until_sent on 64-bit machines
5
6From: Johan Hovold <johan@kernel.org>
7
8commit 79fbf4a550ed6a22e1ae1516113e6c7fa5d56a53 upstream.
9
10Fix overflow bug in tty_wait_until_sent on 64-bit machines, where an
11infinite timeout (0) would be passed to the underlying tty-driver's
12wait_until_sent-operation as a negative timeout (-1), causing it to
13return immediately.
14
15This manifests itself for example as tcdrain() returning immediately,
16drivers not honouring the drain flags when setting terminal attributes,
17or even dropped data on close as a requested infinite closing-wait
18timeout would be ignored.
19
20The first symptom was reported by Asier LLANO who noted that tcdrain()
21returned prematurely when using the ftdi_sio usb-serial driver.
22
23Fix this by passing 0 rather than MAX_SCHEDULE_TIMEOUT (LONG_MAX) to the
24underlying tty driver.
25
26Note that the serial-core wait_until_sent-implementation is not affected
27by this bug due to a lucky chance (comparison to an unsigned maximum
28timeout), and neither is the cyclades one that had an explicit check for
29negative timeouts, but all other tty drivers appear to be affected.
30
31Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
32Reported-by: ZIV-Asier Llano Palacios <asier.llano@cgglobal.com>
33Signed-off-by: Johan Hovold <johan@kernel.org>
34Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
35Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
36
37---
38 drivers/tty/tty_ioctl.c | 12 +++++++++---
39 1 file changed, 9 insertions(+), 3 deletions(-)
40
41--- a/drivers/tty/tty_ioctl.c
42+++ b/drivers/tty/tty_ioctl.c
43@@ -217,11 +217,17 @@ void tty_wait_until_sent(struct tty_stru
44 #endif
45 if (!timeout)
46 timeout = MAX_SCHEDULE_TIMEOUT;
47+
48 if (wait_event_interruptible_timeout(tty->write_wait,
49- !tty_chars_in_buffer(tty), timeout) >= 0) {
50- if (tty->ops->wait_until_sent)
51- tty->ops->wait_until_sent(tty, timeout);
52+ !tty_chars_in_buffer(tty), timeout) < 0) {
53+ return;
54 }
55+
56+ if (timeout == MAX_SCHEDULE_TIMEOUT)
57+ timeout = 0;
58+
59+ if (tty->ops->wait_until_sent)
60+ tty->ops->wait_until_sent(tty, timeout);
61 }
62 EXPORT_SYMBOL(tty_wait_until_sent);
63