Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19e2ad6a authored by Peter Hurley's avatar Peter Hurley Committed by Greg Kroah-Hartman
Browse files

n_tty: Remove overflow tests from receive_buf() path



Always pre-figure the space available in the read_buf and limit
the inbound receive request to that amount.

For compatibility reasons with the non-flow-controlled interface,
n_tty_receive_buf() will continue filling read_buf until all data
has been received or receive_room() returns 0.

Signed-off-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7de971b0
Loading
Loading
Loading
Loading
+37 −48
Original line number Diff line number Diff line
@@ -316,12 +316,9 @@ static inline void n_tty_check_unthrottle(struct tty_struct *tty)
 *	not active.
 */

static void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
{
	if (read_cnt(ldata) < N_TTY_BUF_SIZE) {
		*read_buf_addr(ldata, ldata->read_head) = c;
		ldata->read_head++;
	}
	*read_buf_addr(ldata, ldata->read_head++) = c;
}

/**
@@ -1333,11 +1330,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
			return;
		}
		if (c == '\n') {
			if (read_cnt(ldata) >= N_TTY_BUF_SIZE) {
				if (L_ECHO(tty))
					process_output('\a', tty);
				return;
			}
			if (L_ECHO(tty) || L_ECHONL(tty)) {
				echo_char_raw('\n', ldata);
				commit_echoes(tty);
@@ -1345,8 +1337,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
			goto handle_newline;
		}
		if (c == EOF_CHAR(tty)) {
			if (read_cnt(ldata) >= N_TTY_BUF_SIZE)
				return;
			c = __DISABLED_CHAR;
			goto handle_newline;
		}
@@ -1354,11 +1344,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
		    (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
			parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
				 ? 1 : 0;
			if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk)) {
				if (L_ECHO(tty))
					process_output('\a', tty);
				return;
			}
			/*
			 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
			 */
@@ -1388,12 +1373,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
	}

	parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
	if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk - 1)) {
		/* beep if no space */
		if (L_ECHO(tty))
			process_output('\a', tty);
		return;
	}
	if (L_ECHO(tty)) {
		finish_erasing(ldata);
		if (c == '\n')
@@ -1432,14 +1411,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
			start_tty(tty);
			process_echoes(tty);
		}

		parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
		if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk - 1)) {
			/* beep if no space */
			if (L_ECHO(tty))
				process_output('\a', tty);
			return;
		}
		if (L_ECHO(tty)) {
			finish_erasing(ldata);
			/* Record the column of first canon char. */
@@ -1448,6 +1419,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
			echo_char(c, tty);
			commit_echoes(tty);
		}
		parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
		if (parmrk)
			put_tty_queue(c, ldata);
		put_tty_queue(c, ldata);
@@ -1476,13 +1448,6 @@ n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
			start_tty(tty);
			process_echoes(tty);
		}

		if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - 1)) {
			/* beep if no space */
			if (L_ECHO(tty))
				process_output('\a', tty);
			return;
		}
		if (L_ECHO(tty)) {
			finish_erasing(ldata);
			/* Record the column of first canon char. */
@@ -1691,8 +1656,23 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	int room, n;

	down_read(&tty->termios_rwsem);
	__receive_buf(tty, cp, fp, count);

	while (1) {
		room = receive_room(tty);
		n = min(count, room);
		if (!n)
			break;
		__receive_buf(tty, cp, fp, n);
		cp += n;
		if (fp)
			fp += n;
		count -= n;
	}

	tty->receive_room = room;
	n_tty_check_throttle(tty);
	up_read(&tty->termios_rwsem);
}
@@ -1701,22 +1681,31 @@ static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp,
			      char *fp, int count)
{
	struct n_tty_data *ldata = tty->disc_data;
	int room;
	int room, n, rcvd = 0;

	down_read(&tty->termios_rwsem);

	tty->receive_room = room = receive_room(tty);
	while (1) {
		room = receive_room(tty);
		n = min(count, room);
		if (!n) {
			if (!room)
				ldata->no_room = 1;
	count = min(count, room);
	if (count) {
		__receive_buf(tty, cp, fp, count);
		n_tty_check_throttle(tty);
			break;
		}
		__receive_buf(tty, cp, fp, n);
		cp += n;
		if (fp)
			fp += n;
		count -= n;
		rcvd += n;
	}

	tty->receive_room = room;
	n_tty_check_throttle(tty);
	up_read(&tty->termios_rwsem);

	return count;
	return rcvd;
}

int is_ignored(int sig)