ttys - Add 'ifconsole' option to ttys entries master
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 26 May 2015 20:01:25 +0000 (13:01 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 26 May 2015 20:11:34 +0000 (13:11 -0700)
* Add the 'ifconsole' option.  This allows you to construct a line as shown
  below to enable a getty (e.g. on a serial port) only if the tty is the
  system console.

    ttyd0   "/usr/libexec/getty std.9600"   dialup  on secure ifconsole

  The ifconsole option also silently disables any devices which do not
  exist, removing unnecessary console spam.

* Modify libc and init to handle the new flag.

* Modify the nrelease build and ttys defaults to use this option for
  ttyd0, ttyd1, ttyd2, and ttyd3.

* Avoids previously reported issues with system crashes on certain machines
  whos serial ports are not implemented properly without having to fully
  disable the default ttyd* getty feature.  If the serial port isn't the
  console, it won't be enabled.

* Add a sysctl to the kernel which init needs to test whether a tty is the
  console or not.

Suggested-by: swildner
etc/etc.i386/ttys
etc/etc.x86_64/ttys
include/ttyent.h
lib/libc/gen/getttyent.c
libexec/getty/ttys.5
nrelease/gui/etc/ttys
nrelease/root/etc/ttys
sbin/init/init.c
sys/kern/tty_cons.c

index a5347c3..97c8dca 100644 (file)
@@ -40,14 +40,14 @@ ttyv5       "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv6  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv7  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv8  "/usr/local/bin/xdm -nodaemon"  xterm   off secure
-# Serial terminals
-# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
-ttyd0  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd1  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd2  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd3  "/usr/libexec/getty std.9600"   dialup  off secure
+# Serial terminals - keep it simple
+#
+ttyd0  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd1  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd2  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd3  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
 # Dumb console
-dcons  "/usr/libexec/getty std.9600"   vt100   off secure
+dcons  "/usr/libexec/getty std.9600"   vt100   on secure ifconsole
 # Pseudo terminals
 ttyp0  none                    network
 ttyp1  none                    network
index a5347c3..97c8dca 100644 (file)
@@ -40,14 +40,14 @@ ttyv5       "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv6  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv7  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv8  "/usr/local/bin/xdm -nodaemon"  xterm   off secure
-# Serial terminals
-# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
-ttyd0  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd1  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd2  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd3  "/usr/libexec/getty std.9600"   dialup  off secure
+# Serial terminals - keep it simple
+#
+ttyd0  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd1  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd2  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd3  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
 # Dumb console
-dcons  "/usr/libexec/getty std.9600"   vt100   off secure
+dcons  "/usr/libexec/getty std.9600"   vt100   on secure ifconsole
 # Pseudo terminals
 ttyp0  none                    network
 ttyp1  none                    network
index ee76a0b..8640995 100644 (file)
@@ -48,6 +48,7 @@
 #define        _TTYS_NOGROUP   "none"
 #define        _TTYS_DIALUP    "dialup"
 #define        _TTYS_NETWORK   "network"
+#define        _TTYS_IFCONSOLE "ifconsole"
 
 struct ttyent {
        char    *ty_name;       /* terminal device name */
@@ -57,6 +58,7 @@ struct ttyent {
 #define        TTY_SECURE      0x02    /* allow uid of 0 to login */
 #define        TTY_DIALUP      0x04    /* is a dialup tty */
 #define        TTY_NETWORK     0x08    /* is a network tty */
+#define        TTY_IFCONSOLE   0x10    /* only enable if console */
        int     ty_status;      /* status flags */
        char    *ty_window;     /* command to start up window manager */
        char    *ty_comment;    /* comment field */
index b6dd1d3..f22cc36 100644 (file)
@@ -154,6 +154,8 @@ getttyent(void)
                        tty.ty_status |= TTY_DIALUP;
                else if (scmp(_TTYS_NETWORK))
                        tty.ty_status |= TTY_NETWORK;
+               else if (scmp(_TTYS_IFCONSOLE))
+                       tty.ty_status |= TTY_IFCONSOLE;
                else if (vcmp(_TTYS_WINDOW))
                        tty.ty_window = value(p);
                else if (vcmp(_TTYS_GROUP))
index ce51e31..c59935f 100644 (file)
@@ -103,7 +103,10 @@ should (should not) execute the command given in the second field,
 while ``secure'' (if ``on'' is also specified) allows users with a
 uid of 0 to login on
 this line.
-The flag ``dialin'' indicates that a tty entry describes a dialin
+The flag ``ifconsole'' disables the tty entry if it is not the console.
+That is, you can construct a tty entry, set to 'on', that you intend to
+only be active if that tty is the console.
+The flag ``dialup'' indicates that a tty entry describes a dialup
 line, and ``network'' indicates that a tty entry provides a
 network connection.
 Either of these strings may also be specified in the terminal type
index d13b57e..89bb0ff 100644 (file)
@@ -40,14 +40,14 @@ ttyv5       "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv6  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv7  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv8  "/usr/pkg/bin/xdm -nodaemon"    xterm   off secure
-# Serial terminals
-# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
-ttyd0  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd1  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd2  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd3  "/usr/libexec/getty std.9600"   dialup  off secure
+# Serial terminals - keep it simple
+#
+ttyd0  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd1  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd2  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd3  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
 # Dumb console
-dcons  "/usr/libexec/getty std.9600"   vt100   off secure
+dcons  "/usr/libexec/getty std.9600"   vt100   on secure ifconsole
 # Pseudo terminals
 ttyp0  none                    network
 ttyp1  none                    network
index aff58f9..4ce4193 100644 (file)
@@ -39,13 +39,12 @@ ttyv5       "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv6  "/usr/libexec/getty Pc"         cons25  on  secure
 ttyv7  "/usr/libexec/getty Pc"         cons25  on  secure
 #ttyv8 "/usr/local/bin/xdm -nodaemon"  xterm   off secure
-# Serial terminals
-# vt100-color seems to work best when talking to the serial port
-# from a cu/tip running on an xterm.
-ttyd0  "/usr/libexec/getty std.9600"   vt100-color off secure
-ttyd1  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd2  "/usr/libexec/getty std.9600"   dialup  off secure
-ttyd3  "/usr/libexec/getty std.9600"   dialup  off secure
+# Serial terminals - keep it simple
+#
+ttyd0  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd1  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd2  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
+ttyd3  "/usr/libexec/getty std.9600"   dialup  on secure ifconsole
 # Pseudo terminals
 ttyp0  none                    network
 ttyp1  none                    network
index 08f205d..d5a796f 100644 (file)
@@ -149,6 +149,7 @@ static void transition(state_t);
 
 static void    free_session(session_t *);
 static session_t *new_session(session_t *, int, struct ttyent *);
+static void    adjttyent(struct ttyent *typ);
 
 static char    **construct_argv(char *);
 static void    start_window_system(session_t *);
@@ -983,6 +984,36 @@ free_session(session_t *sp)
        free(sp);
 }
 
+static
+void
+adjttyent(struct ttyent *typ)
+{
+       struct stat st;
+       uint32_t rdev;
+       char *devpath;
+       size_t rdev_size = sizeof(rdev);
+
+       if (typ->ty_name == NULL)
+               return;
+
+       /*
+        * IFCONSOLE option forces tty off if not the console.
+        */
+       if (typ->ty_status & TTY_IFCONSOLE) {
+               asprintf(&devpath, "%s%s", _PATH_DEV, typ->ty_name);
+               if (stat(devpath, &st) < 0 ||
+                   sysctlbyname("kern.console_rdev",
+                                &rdev, &rdev_size,
+                                NULL, 0) < 0) {
+                       /* device does not exist or no sysctl, disable */
+                       typ->ty_status &= ~TTY_ON;
+               } else if (rdev != st.st_rdev) {
+                       typ->ty_status &= ~TTY_ON;
+               }
+               free(devpath);
+       }
+}
+
 /*
  * Allocate a new session descriptor.
  * Mark it SE_PRESENT.
@@ -993,19 +1024,18 @@ new_session(session_t *sprev, int session_index, struct ttyent *typ)
        session_t *sp;
        int fd;
 
-       if ((typ->ty_status & TTY_ON) == 0 ||
-           typ->ty_name == 0 ||
-           typ->ty_getty == 0)
+       if (typ->ty_name == NULL || typ->ty_getty == NULL)
+               return 0;
+
+       if ((typ->ty_status & TTY_ON) == 0)
                return 0;
 
        sp = (session_t *) calloc(1, sizeof (session_t));
 
+       asprintf(&sp->se_device, "%s%s", _PATH_DEV, typ->ty_name);
        sp->se_index = session_index;
        sp->se_flags |= SE_PRESENT;
 
-       sp->se_device = malloc(sizeof(_PATH_DEV) + strlen(typ->ty_name));
-       sprintf(sp->se_device, "%s%s", _PATH_DEV, typ->ty_name);
-
        /*
         * Attempt to open the device, if we get "device not configured"
         * then don't add the device to the session list.
@@ -1131,9 +1161,11 @@ read_ttys(void)
         * Allocate a session entry for each active port.
         * Note that sp starts at 0.
         */
-       while ((typ = getttyent()) != NULL)
+       while ((typ = getttyent()) != NULL) {
+               adjttyent(typ);
                if ((snext = new_session(sp, ++session_index, typ)) != NULL)
                        sp = snext;
+       }
 
        endttyent();
 
@@ -1385,6 +1417,7 @@ clean_ttys(void)
        while ((typ = getttyent()) != NULL) {
                ++session_index;
 
+               adjttyent(typ);
                for (sprev = NULL, sp = sessions; sp; sprev = sp, sp = sp->se_next)
                        if (strcmp(typ->ty_name, sp->se_device + devlen) == 0)
                                break;
index 9d8c893..779399a 100644 (file)
@@ -129,6 +129,9 @@ struct consdev *cn_tab;             /* physical console device info */
 struct consdev *gdb_tab;       /* physical gdb debugger device info */
 
 SYSCTL_INT(_kern, OID_AUTO, sysbeep_enable, CTLFLAG_RW, &sysbeep_enable, 0, "");
+static uint32_t console_rdev;
+SYSCTL_INT(_kern, OID_AUTO, console_rdev, CTLFLAG_RW,
+       &console_rdev, 0, "");
 
 CONS_DRIVER(cons, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 SET_DECLARE(cons_set, struct consdev);
@@ -225,6 +228,13 @@ cninit_finish(void)
 
        cn_fwd_ops = dev_ops_intercept(cn_tab->cn_dev, &cn_iops);
        cn_dev = cn_tab->cn_dev;
+       if (cn_dev) {
+               console_rdev = makeudev(cn_dev->si_umajor,
+                                       (cn_dev->si_uminor == 255 ?
+                                           0 : cn_dev->si_uminor));
+       } else {
+               console_rdev = 0;
+       }
        console_pausing = 0;
 }