]> err.no Git - util-linux/commitdiff
login: check that after tty reopen we still work with a terminal
authorKarel Zak <kzak@redhat.com>
Thu, 28 Jan 2010 15:25:52 +0000 (16:25 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 16 Feb 2010 08:58:57 +0000 (09:58 +0100)
 * the login code assumes that stdin is a terminal, it's better to
   check (by isatty()) that after tty reopen we still have a terminal

 * this patch also removes very old obscure fallback for situations where
   ttyname() returns nothing (then ttyn = "/dev/tty??"). I guess that the
   fake string was originally for utmp records or so. Currently (in last 10
   years...) code requires that the tty name is a real open-able file.
   It means the fake tty name is completely useless.

Reported-by: Yann Droneaud <yann@droneaud.fr>
Signed-off-by: Karel Zak <kzak@redhat.com>
login-utils/login.c

index fdc8078ddcd54fb420f884560fc632d4a5111599..1550388c4574207857ae6843041eeff3cba52d39 100644 (file)
@@ -200,6 +200,13 @@ opentty(const char * tty) {
                exit(1);
        }
 
+       if (!isatty(fd)) {
+               close(fd);
+               syslog(LOG_ERR, _("FATAL: %s is not a terminal"), tty);
+               sleep(1);
+               exit(1);
+       }
+
        flags = fcntl(fd, F_GETFL);
        flags &= ~O_NONBLOCK;
        fcntl(fd, F_SETFL, flags);
@@ -222,7 +229,9 @@ static void
 check_ttyname(char *ttyn) {
        struct stat statbuf;
 
-       if (lstat(ttyn, &statbuf)
+       if (ttyn == NULL
+           || *ttyn == '\0'
+           || lstat(ttyn, &statbuf)
            || !S_ISCHR(statbuf.st_mode)
            || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))
            || (access(ttyn, R_OK | W_OK) != 0)) {
@@ -378,7 +387,7 @@ main(int argc, char **argv)
     int ask, fflag, hflag, pflag, cnt, errsv;
     int quietlog, passwd_req;
     char *domain, *ttyn;
-    char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_DEV_TTY) + 10];
+    char tbuf[MAXPATHLEN + 2];
     char *termenv;
     char *childArgv[10];
     char *buff;
@@ -495,14 +504,9 @@ main(int argc, char **argv)
     for (cnt = getdtablesize(); cnt > 2; cnt--)
       close(cnt);
 
+    /* note that libc checks that the file descriptor is a terminal, so we don't
+     * have to call isatty() here */
     ttyn = ttyname(0);
-
-    if (ttyn == NULL || *ttyn == '\0') {
-       /* no snprintf required - see definition of tname */
-       snprintf(tname, sizeof(tname), "%s??", _PATH_DEV_TTY);
-       ttyn = tname;
-    }
-
     check_ttyname(ttyn);
 
     if (strncmp(ttyn, "/dev/", 5) == 0)