LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline
@ 2015-04-16 18:57 Joseph Salisbury
  2015-04-16 18:57 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 1/1] " Joseph Salisbury
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Joseph Salisbury @ 2015-04-16 18:57 UTC (permalink / raw)
  To: gregkh, luis.henriques, sasha.levin, kamal.mostafa, jslaby
  Cc: peter, linux-kernel, stable

Hello,

Please consider including mainline commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e 
in the next v3.12.y, v3.13.y-ckt, v3.14.y, 3.16.y-ckt, 3.18.y, and 3.19.y stable releases.  
It was included mainline as of v4.0-rc1.  It has been tested and confirmed to resolve
http://bugs.launchpad.net/bugs/1381005 .  This bug was introduced in v3.12-rc1 when 
commit 24a89d1 was applied.  This commit is not needed in stable kernels prior to 
v3.12.y.


commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e
Author: Peter Hurley <peter@hurleysoftware.com>
Date:   Fri Jan 16 15:05:39 2015 -0500

    n_tty: Fix read buffer overwrite when no newline


This commit does not apply cleanly to the kernels versions mentined, so I performed 
a backport, which is in email 1/1.

The 3.12.y and 3.13.y-ckt stable releases first need a cherry pick of commit
5c32d12378313e0096ea0d450462aa638a90fb6e.  This is because in commit 5c32d123
n_tty_receive_buf and n_tty_receive_buf2 were merged into n_tty_receive_buf_common,
which is where the backport makes the needed changes. 


Sincerely,

Joseph Salisbury

Peter Hurley (1):
  n_tty: Fix read buffer overwrite when no newline

 drivers/tty/n_tty.c | 106 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 79 insertions(+), 27 deletions(-)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 1/1] n_tty: Fix read buffer overwrite when no newline
  2015-04-16 18:57 [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline Joseph Salisbury
@ 2015-04-16 18:57 ` Joseph Salisbury
  2015-04-21 16:15 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] " Jiri Slaby
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Joseph Salisbury @ 2015-04-16 18:57 UTC (permalink / raw)
  To: gregkh, luis.henriques, sasha.levin, kamal.mostafa, jslaby
  Cc: peter, linux-kernel, stable

From: Peter Hurley <peter@hurleysoftware.com>

BugLink: http://bugs.launchpad.net/bugs/1381005

In canon mode, the read buffer head will advance over the buffer tail
if the input > 4095 bytes without receiving a line termination char.

Discard additional input until a line termination is received.
Before evaluating for overflow, the 'room' value is normalized for
I_PARMRK and 1 byte is reserved for line termination (even in !icanon
mode, in case the mode is switched). The following table shows the
transform:

 actual buffer |  'room' value before overflow calc
  space avail  |    !I_PARMRK    |    I_PARMRK
 --------------------------------------------------
      0        |       -1        |       -1
      1        |        0        |        0
      2        |        1        |        0
      3        |        2        |        0
      4+       |        3        |        1

When !icanon or when icanon and the read buffer contains newlines,
normalized 'room' values of -1 and 0 are clamped to 0, and
'overflow' is 0, so read_head is not adjusted and the input i/o loop
exits (setting no_room if called from flush_to_ldisc()). No input
is discarded since the reader does have input available to read
which ensures forward progress.

When icanon and the read buffer does not contain newlines and the
normalized 'room' value is 0, then overflow and room are reset to 1,
so that the i/o loop will process the next input char normally
(except for parity errors which are ignored). Thus, erasures, signalling
chars, 7-bit mode, etc. will continue to be handled properly.

If the input char processed was not a line termination char, then
the canon_head index will not have advanced, so the normalized 'room'
value will now be -1 and 'overflow' will be set, which indicates the
read_head can safely be reset, effectively erasing the last char
processed.

If the input char processed was a line termination, then the
canon_head index will have advanced, so 'overflow' is cleared to 0,
the read_head is not reset, and 'room' is cleared to 0, which exits
the i/o loop (because the reader now have input available to read
which ensures forward progress).

Note that it is possible for a line termination to be received, and
for the reader to copy the line to the user buffer before the
input i/o loop is ready to process the next input char. This is
why the i/o loop recomputes the room/overflow state with every
input char while handling overflow.

Finally, if the input data was processed without receiving
a line termination (so that overflow is still set), the pty
driver must receive a write wakeup. A pty writer may be waiting
to write more data in n_tty_write() but without unthrottling
here that wakeup will not arrive, and forward progress will halt.
(Normally, the pty writer is woken when the reader reads data out
of the buffer and more space become available).

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(backported from commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e)
Signed-off-by: Joseph Salisbury <joseph.salisbury@canonical.com>
---
 drivers/tty/n_tty.c | 106 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 79 insertions(+), 27 deletions(-)

diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 4ddfa60..6f8cf3a 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -247,8 +247,6 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
 
 static void n_tty_check_throttle(struct tty_struct *tty)
 {
-	if (tty->driver->type == TTY_DRIVER_TYPE_PTY)
-		return;
 	/*
 	 * Check the remaining room for the input canonicalization
 	 * mode.  We don't want to throttle the driver if we're in
@@ -1512,23 +1510,6 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag)
 		n_tty_receive_char_flagged(tty, c, flag);
 }
 
-/**
- *	n_tty_receive_buf	-	data receive
- *	@tty: terminal device
- *	@cp: buffer
- *	@fp: flag buffer
- *	@count: characters
- *
- *	Called by the terminal driver when a block of characters has
- *	been received. This function must be called from soft contexts
- *	not from interrupt context. The driver is responsible for making
- *	calls one at a time and in order (or using flush_to_ldisc)
- *
- *	n_tty_receive_buf()/producer path:
- *		claims non-exclusive termios_rwsem
- *		publishes read_head and canon_head
- */
-
 static void
 n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
 			   char *fp, int count)
@@ -1684,24 +1665,85 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
 	}
 }
 
+/**
+ *	n_tty_receive_buf_common	-	process input
+ *	@tty: device to receive input
+ *	@cp: input chars
+ *	@fp: flags for each char (if NULL, all chars are TTY_NORMAL)
+ *	@count: number of input chars in @cp
+ *
+ *	Called by the terminal driver when a block of characters has
+ *	been received. This function must be called from soft contexts
+ *	not from interrupt context. The driver is responsible for making
+ *	calls one at a time and in order (or using flush_to_ldisc)
+ *
+ *	Returns the # of input chars from @cp which were processed.
+ *
+ *	In canonical mode, the maximum line length is 4096 chars (including
+ *	the line termination char); lines longer than 4096 chars are
+ *	truncated. After 4095 chars, input data is still processed but
+ *	not stored. Overflow processing ensures the tty can always
+ *	receive more input until at least one line can be read.
+ *
+ *	In non-canonical mode, the read buffer will only accept 4095 chars;
+ *	this provides the necessary space for a newline char if the input
+ *	mode is switched to canonical.
+ *
+ *	Note it is possible for the read buffer to _contain_ 4096 chars
+ *	in non-canonical mode: the read buffer could already contain the
+ *	maximum canon line of 4096 chars when the mode is switched to
+ *	non-canonical.
+ *
+ *	n_tty_receive_buf()/producer path:
+ *		claims non-exclusive termios_rwsem
+ *		publishes commit_head or canon_head
+ */
 static int
 n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
 			 char *fp, int count, int flow)
 {
 	struct n_tty_data *ldata = tty->disc_data;
-	int room, n, rcvd = 0;
+	int room, n, rcvd = 0, overflow;
 
 	down_read(&tty->termios_rwsem);
 
 	while (1) {
-		room = receive_room(tty);
+		/*
+		 * When PARMRK is set, each input char may take up to 3 chars
+		 * in the read buf; reduce the buffer space avail by 3x
+		 *
+		 * If we are doing input canonicalization, and there are no
+		 * pending newlines, let characters through without limit, so
+		 * that erase characters will be handled.  Other excess
+		 * characters will be beeped.
+		 *
+		 * paired with store in *_copy_from_read_buf() -- guarantees
+		 * the consumer has loaded the data in read_buf up to the new
+		 * read_tail (so this producer will not overwrite unread data)
+		 */
+		size_t tail = ldata->read_tail;
+
+		room = N_TTY_BUF_SIZE - (ldata->read_head - tail);
+		if (I_PARMRK(tty))
+			room = (room + 2) / 3;
+		room--;
+		if (room <= 0) {
+			overflow = ldata->icanon && ldata->canon_head == tail;
+			if (overflow && room < 0)
+				ldata->read_head--;
+			room = overflow;
+			ldata->no_room = flow && !room;
+		} else
+			overflow = 0;
+
 		n = min(count, room);
-		if (!n) {
-			if (flow && !room)
-				ldata->no_room = 1;
+		if (!n)
 			break;
-		}
-		__receive_buf(tty, cp, fp, n);
+
+		/* ignore parity errors if handling overflow */
+		if (!overflow || !fp || *fp != TTY_PARITY)
+			__receive_buf(tty, cp, fp, n);
+
 		cp += n;
 		if (fp)
 			fp += n;
@@ -1710,7 +1752,17 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
 	}
 
 	tty->receive_room = room;
-	n_tty_check_throttle(tty);
+
+	/* Unthrottle if handling overflow on pty */
+	if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
+		if (overflow) {
+			tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
+			tty_unthrottle_safe(tty);
+			__tty_set_flow_change(tty, 0);
+		}
+	} else
+		n_tty_check_throttle(tty);
+
 	up_read(&tty->termios_rwsem);
 
 	return rcvd;
-- 
2.1.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline
  2015-04-16 18:57 [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline Joseph Salisbury
  2015-04-16 18:57 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 1/1] " Joseph Salisbury
@ 2015-04-21 16:15 ` Jiri Slaby
  2015-04-22 13:18 ` Luis Henriques
  2015-05-01 15:57 ` Kamal Mostafa
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Slaby @ 2015-04-21 16:15 UTC (permalink / raw)
  To: Joseph Salisbury, gregkh, luis.henriques, sasha.levin, kamal.mostafa
  Cc: peter, linux-kernel, stable

On 04/16/2015, 08:57 PM, Joseph Salisbury wrote:
> Hello,
> 
> Please consider including mainline commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e 
> in the next v3.12.y, v3.13.y-ckt, v3.14.y, 3.16.y-ckt, 3.18.y, and 3.19.y stable releases.  
> It was included mainline as of v4.0-rc1.  It has been tested and confirmed to resolve
> http://bugs.launchpad.net/bugs/1381005 .  This bug was introduced in v3.12-rc1 when 
> commit 24a89d1 was applied.  This commit is not needed in stable kernels prior to 
> v3.12.y.
> 
> 
> commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e
> Author: Peter Hurley <peter@hurleysoftware.com>
> Date:   Fri Jan 16 15:05:39 2015 -0500
> 
>     n_tty: Fix read buffer overwrite when no newline
> 
> 
> This commit does not apply cleanly to the kernels versions mentined, so I performed 
> a backport, which is in email 1/1.
> 
> The 3.12.y and 3.13.y-ckt stable releases first need a cherry pick of commit
> 5c32d12378313e0096ea0d450462aa638a90fb6e.  This is because in commit 5c32d123
> n_tty_receive_buf and n_tty_receive_buf2 were merged into n_tty_receive_buf_common,
> which is where the backport makes the needed changes. 

I did for 3.12. Thanks.

-- 
js
suse labs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline
  2015-04-16 18:57 [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline Joseph Salisbury
  2015-04-16 18:57 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 1/1] " Joseph Salisbury
  2015-04-21 16:15 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] " Jiri Slaby
@ 2015-04-22 13:18 ` Luis Henriques
  2015-05-01 15:57 ` Kamal Mostafa
  3 siblings, 0 replies; 5+ messages in thread
From: Luis Henriques @ 2015-04-22 13:18 UTC (permalink / raw)
  To: Joseph Salisbury
  Cc: gregkh, sasha.levin, kamal.mostafa, jslaby, peter, linux-kernel, stable

On Thu, Apr 16, 2015 at 02:57:26PM -0400, Joseph Salisbury wrote:
> Hello,
> 
> Please consider including mainline commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e 
> in the next v3.12.y, v3.13.y-ckt, v3.14.y, 3.16.y-ckt, 3.18.y, and 3.19.y stable releases.  
> It was included mainline as of v4.0-rc1.  It has been tested and confirmed to resolve
> http://bugs.launchpad.net/bugs/1381005 .  This bug was introduced in v3.12-rc1 when 
> commit 24a89d1 was applied.  This commit is not needed in stable kernels prior to 
> v3.12.y.
> 
> 
> commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e
> Author: Peter Hurley <peter@hurleysoftware.com>
> Date:   Fri Jan 16 15:05:39 2015 -0500
> 
>     n_tty: Fix read buffer overwrite when no newline
> 
> 
> This commit does not apply cleanly to the kernels versions mentined, so I performed 
> a backport, which is in email 1/1.
> 
> The 3.12.y and 3.13.y-ckt stable releases first need a cherry pick of commit
> 5c32d12378313e0096ea0d450462aa638a90fb6e.  This is because in commit 5c32d123
> n_tty_receive_buf and n_tty_receive_buf2 were merged into n_tty_receive_buf_common,
> which is where the backport makes the needed changes. 
> 
> 

Thanks a lot for the backport.  I'm queuing it for the 3.16 kernel.

Cheers,
--
Luís


> Sincerely,
> 
> Joseph Salisbury
> 
> Peter Hurley (1):
>   n_tty: Fix read buffer overwrite when no newline
> 
>  drivers/tty/n_tty.c | 106 +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 79 insertions(+), 27 deletions(-)
> 
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline
  2015-04-16 18:57 [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline Joseph Salisbury
                   ` (2 preceding siblings ...)
  2015-04-22 13:18 ` Luis Henriques
@ 2015-05-01 15:57 ` Kamal Mostafa
  3 siblings, 0 replies; 5+ messages in thread
From: Kamal Mostafa @ 2015-05-01 15:57 UTC (permalink / raw)
  To: Joseph Salisbury
  Cc: gregkh, luis.henriques, sasha.levin, kamal.mostafa, jslaby,
	peter, linux-kernel, stable

On Thu, 2015-04-16 at 14:57 -0400, Joseph Salisbury wrote:
> Hello,
> 
> Please consider including mainline commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e 
> in the next v3.12.y, v3.13.y-ckt, v3.14.y, 3.16.y-ckt, 3.18.y, and 3.19.y stable releases.  
> It was included mainline as of v4.0-rc1.  It has been tested and confirmed to resolve
> http://bugs.launchpad.net/bugs/1381005 .  This bug was introduced in v3.12-rc1 when 
> commit 24a89d1 was applied.  This commit is not needed in stable kernels prior to 
> v3.12.y.
> 
> 
> commit fb5ef9e7da39968fec6d6f37f20a23d23740c75e
> Author: Peter Hurley <peter@hurleysoftware.com>
> Date:   Fri Jan 16 15:05:39 2015 -0500
> 
>     n_tty: Fix read buffer overwrite when no newline
> 
> 
> This commit does not apply cleanly to the kernels versions mentined, so I performed 
> a backport, which is in email 1/1.
> 
> The 3.12.y and 3.13.y-ckt stable releases first need a cherry pick of commit
> 5c32d12378313e0096ea0d450462aa638a90fb6e.  This is because in commit 5c32d123
> n_tty_receive_buf and n_tty_receive_buf2 were merged into n_tty_receive_buf_common,
> which is where the backport makes the needed changes. 
> 
> 
> Sincerely,
> 
> Joseph Salisbury
> 
> Peter Hurley (1):
>   n_tty: Fix read buffer overwrite when no newline
> 
>  drivers/tty/n_tty.c | 106 +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 79 insertions(+), 27 deletions(-)
> 

Queued up for 3.13-stable.  Thanks, Joseph and Peter!

 -Kamal



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-01 15:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-16 18:57 [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] n_tty: Fix read buffer overwrite when no newline Joseph Salisbury
2015-04-16 18:57 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 1/1] " Joseph Salisbury
2015-04-21 16:15 ` [v3.12.y][v3.13.y-ckt][3.14.y][3.16.y-ckt][3.18.y][3.19.y][V2][PATCH 0/1] " Jiri Slaby
2015-04-22 13:18 ` Luis Henriques
2015-05-01 15:57 ` Kamal Mostafa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).