From: Matthew Dillon Date: Tue, 26 May 2015 20:01:25 +0000 (-0700) Subject: ttys - Add 'ifconsole' option to ttys entries X-Git-Url: https://gitweb.dragonflybsd.org/~nant/dragonfly.git/commitdiff_plain/fda9d7927d5b74c2012759fea990a5cd57658131 ttys - Add 'ifconsole' option to ttys entries * 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 --- diff --git a/etc/etc.i386/ttys b/etc/etc.i386/ttys index a5347c3c08..97c8dca684 100644 --- a/etc/etc.i386/ttys +++ b/etc/etc.i386/ttys @@ -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 diff --git a/etc/etc.x86_64/ttys b/etc/etc.x86_64/ttys index a5347c3c08..97c8dca684 100644 --- a/etc/etc.x86_64/ttys +++ b/etc/etc.x86_64/ttys @@ -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 diff --git a/include/ttyent.h b/include/ttyent.h index ee76a0b19a..8640995914 100644 --- a/include/ttyent.h +++ b/include/ttyent.h @@ -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 */ diff --git a/lib/libc/gen/getttyent.c b/lib/libc/gen/getttyent.c index b6dd1d30e3..f22cc36d10 100644 --- a/lib/libc/gen/getttyent.c +++ b/lib/libc/gen/getttyent.c @@ -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)) diff --git a/libexec/getty/ttys.5 b/libexec/getty/ttys.5 index ce51e31d81..c59935f2c7 100644 --- a/libexec/getty/ttys.5 +++ b/libexec/getty/ttys.5 @@ -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 diff --git a/nrelease/gui/etc/ttys b/nrelease/gui/etc/ttys index d13b57eca1..89bb0ff868 100644 --- a/nrelease/gui/etc/ttys +++ b/nrelease/gui/etc/ttys @@ -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 diff --git a/nrelease/root/etc/ttys b/nrelease/root/etc/ttys index aff58f9736..4ce4193d8c 100644 --- a/nrelease/root/etc/ttys +++ b/nrelease/root/etc/ttys @@ -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 diff --git a/sbin/init/init.c b/sbin/init/init.c index 08f205d24b..d5a796f916 100644 --- a/sbin/init/init.c +++ b/sbin/init/init.c @@ -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; diff --git a/sys/kern/tty_cons.c b/sys/kern/tty_cons.c index 9d8c8936d9..779399ac04 100644 --- a/sys/kern/tty_cons.c +++ b/sys/kern/tty_cons.c @@ -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; }