From: Karel Zak Date: Thu, 28 Jan 2010 15:25:52 +0000 (+0100) Subject: login: check that after tty reopen we still work with a terminal X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73e347ec0ed1b2d6aec08dcf9c3841796171cea7;p=util-linux login: check that after tty reopen we still work with a terminal * 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 Signed-off-by: Karel Zak --- diff --git a/login-utils/login.c b/login-utils/login.c index fdc8078d..1550388c 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -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)