lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 15 Jun 2010 11:10:59 -0700
From:	Howard Chu <hyc@...as.com>
To:	linux-kernel <linux-kernel@...r.kernel.org>,
	Greg KH <greg@...ah.com>, Alan Cox <alan@...rguk.ukuu.org.uk>
Subject: [PATCH 1/2] tty: add EXTPROC support for LINEMODE

This adds the basic driver support. Tested on x86 and x86-64.

Signed-off-by: Howard Chu <hyc@...as.com>
---
  drivers/char/n_tty.c           |   25 ++++++++++++++++++++++---
  drivers/char/pty.c             |   13 +++++++++++++
  drivers/char/tty_ioctl.c       |   18 ++++++++++++------
  fs/compat_ioctl.c              |    1 +
  include/asm-generic/ioctls.h   |    2 ++
  include/asm-generic/termbits.h |    1 +
  include/linux/tty.h            |    1 +
  7 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index bdae832..67caa01 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1102,6 +1102,11 @@ static inline void n_tty_receive_char(struct tty_struct 
*tty, unsigned char c)
  	if (I_IUCLC(tty) && L_IEXTEN(tty))
  		c = tolower(c);

+	if (L_EXTPROC(tty)) {
+		put_tty_queue(c, tty);
+		return;
+	}
+
  	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
  	    I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) &&
  	    c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) {
@@ -1409,7 +1414,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, 
const unsigned char *cp,

  	n_tty_set_room(tty);

-	if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) {
+	if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
+		L_EXTPROC(tty)) {
  		kill_fasync(&tty->fasync, SIGIO, POLL_IN);
  		if (waitqueue_active(&tty->read_wait))
  			wake_up_interruptible(&tty->read_wait);
@@ -1585,7 +1591,7 @@ static int n_tty_open(struct tty_struct *tty)
  static inline int input_available_p(struct tty_struct *tty, int amt)
  {
  	tty_flush_to_ldisc(tty);
-	if (tty->icanon) {
+	if (tty->icanon && !L_EXTPROC(tty)) {
  		if (tty->canon_data)
  			return 1;
  	} else if (tty->read_cnt >= (amt ? amt : 1))
@@ -1632,6 +1638,11 @@ static int copy_from_read_buf(struct tty_struct *tty,
  		spin_lock_irqsave(&tty->read_lock, flags);
  		tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
  		tty->read_cnt -= n;
+		/* Check if last character is EOF */
+		if (L_EXTPROC(tty) && tty->icanon) {
+			if (!tty->read_cnt && *b[n-1] == EOF_CHAR(tty))
+				n--;
+		}
  		spin_unlock_irqrestore(&tty->read_lock, flags);
  		*b += n;
  		*nr -= n;
@@ -1767,6 +1778,14 @@ do_it_again:
  				break;
  			}
  			nr--;
+			if (cs & TIOCPKT_IOCTL) {
+				c = sizeof(struct termios);
+				if (c > nr)
+					c = nr;
+				copy_to_user(b, tty->link->termios, c);
+				nr -= c;
+				b += c;
+			}
  			break;
  		}
  		/* This statement must be first before checking for input
@@ -1812,7 +1831,7 @@ do_it_again:
  			nr--;
  		}

-		if (tty->icanon) {
+		if (tty->icanon && !L_EXTPROC(tty)) {
  			/* N.B. avoid overrun if nr == 0 */
  			while (nr && tty->read_cnt) {
  				int eol;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d83a431..c429e9f 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -171,6 +171,15 @@ static int pty_set_lock(struct tty_struct *tty, int 
__user *arg)
  	return 0;
  }

+/* Send a signal to the slave */
+static int pty_signal(struct tty_struct *tty, int sig)
+{
+	if (tty->link) {
+		kill_pgrp(tty->link->pgrp, sig, 1);
+	}
+	return 0;
+}
+
  static void pty_flush_buffer(struct tty_struct *tty)
  {
  	struct tty_struct *to = tty->link;
@@ -321,6 +330,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct 
file *file,
  	switch (cmd) {
  	case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */
  		return pty_set_lock(tty, (int __user *) arg);
+	case TIOCSIG:    /* Send signal to other side of pty */
+		return pty_signal(tty, (int) arg);
  	}
  	return -ENOIOCTLCMD;
  }
@@ -476,6 +487,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, struct 
file *file,
  		return pty_set_lock(tty, (int __user *)arg);
  	case TIOCGPTN: /* Get PT Number */
  		return put_user(tty->index, (unsigned int __user *)arg);
+	case TIOCSIG:    /* Send signal to other side of pty */
+		return pty_signal(tty, (int) arg);
  	}

  	return -ENOIOCTLCMD;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 6bd5f88..0c18899 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -517,19 +517,25 @@ static void change_termios(struct tty_struct *tty, 
struct ktermios *new_termios)

  	/* See if packet mode change of state. */
  	if (tty->link && tty->link->packet) {
+		int extproc = (old_termios.c_lflag & EXTPROC) |
+				(tty->termios->c_lflag & EXTPROC);
  		int old_flow = ((old_termios.c_iflag & IXON) &&
  				(old_termios.c_cc[VSTOP] == '\023') &&
  				(old_termios.c_cc[VSTART] == '\021'));
  		int new_flow = (I_IXON(tty) &&
  				STOP_CHAR(tty) == '\023' &&
  				START_CHAR(tty) == '\021');
-		if (old_flow != new_flow) {
+		if ((old_flow != new_flow) || extproc) {
  			spin_lock_irqsave(&tty->ctrl_lock, flags);
-			tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
-			if (new_flow)
-				tty->ctrl_status |= TIOCPKT_DOSTOP;
-			else
-				tty->ctrl_status |= TIOCPKT_NOSTOP;
+			if (old_flow != new_flow) {
+				tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
+				if (new_flow)
+					tty->ctrl_status |= TIOCPKT_DOSTOP;
+				else
+					tty->ctrl_status |= TIOCPKT_NOSTOP;
+			}
+			if (extproc)
+				tty->ctrl_status |= TIOCPKT_IOCTL;
  			spin_unlock_irqrestore(&tty->ctrl_lock, flags);
  			wake_up_interruptible(&tty->link->read_wait);
  		}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 641640d..766636d 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -966,6 +966,7 @@ COMPATIBLE_IOCTL(TIOCGPGRP)
  COMPATIBLE_IOCTL(TIOCGPTN)
  COMPATIBLE_IOCTL(TIOCSPTLCK)
  COMPATIBLE_IOCTL(TIOCSERGETLSR)
+COMPATIBLE_IOCTL(TIOCSIG)
  #ifdef TCGETS2
  COMPATIBLE_IOCTL(TCGETS2)
  COMPATIBLE_IOCTL(TCSETS2)
diff --git a/include/asm-generic/ioctls.h b/include/asm-generic/ioctls.h
index a799e20..87661c8 100644
--- a/include/asm-generic/ioctls.h
+++ b/include/asm-generic/ioctls.h
@@ -69,6 +69,7 @@
  #define TCSETX		0x5433
  #define TCSETXF		0x5434
  #define TCSETXW		0x5435
+#define TIOCSIG		_IOW('T', 0x36, int)  /* pty: generate signal */

  #define FIONCLEX	0x5450
  #define FIOCLEX		0x5451
@@ -104,6 +105,7 @@
  #define TIOCPKT_START		 8
  #define TIOCPKT_NOSTOP		16
  #define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64

  #define TIOCSER_TEMT	0x01	/* Transmitter physically empty */

diff --git a/include/asm-generic/termbits.h b/include/asm-generic/termbits.h
index 1c9773d..232b478 100644
--- a/include/asm-generic/termbits.h
+++ b/include/asm-generic/termbits.h
@@ -178,6 +178,7 @@ struct ktermios {
  #define FLUSHO	0010000
  #define PENDIN	0040000
  #define IEXTEN	0100000
+#define EXTPROC	0200000

  /* tcflow() and TCXONC use these */
  #define	TCOOFF		0
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 4409967..3cfe448 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -178,6 +178,7 @@ struct tty_bufhead {
  #define L_FLUSHO(tty)	_L_FLAG((tty), FLUSHO)
  #define L_PENDIN(tty)	_L_FLAG((tty), PENDIN)
  #define L_IEXTEN(tty)	_L_FLAG((tty), IEXTEN)
+#define L_EXTPROC(tty)	_L_FLAG((tty), EXTPROC)

  struct device;
  struct signal_struct;
-- 1.7.0.4


-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ