diff options
author | Karel Zak | 2010-01-28 16:25:52 +0100 |
---|---|---|
committer | Karel Zak | 2010-01-28 16:25:52 +0100 |
commit | 8bee984a93cdf62b3cc84bb9fbfe023b6f554818 (patch) | |
tree | 337d389ac30fe6d02a03b2bee7d0b3c9817fa2d1 /login-utils/login.c | |
parent | login: use fd instead of pathname for update tty's owner and permissions (diff) | |
download | kernel-qcow2-util-linux-8bee984a93cdf62b3cc84bb9fbfe023b6f554818.tar.gz kernel-qcow2-util-linux-8bee984a93cdf62b3cc84bb9fbfe023b6f554818.tar.xz kernel-qcow2-util-linux-8bee984a93cdf62b3cc84bb9fbfe023b6f554818.zip |
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 <yann@droneaud.fr>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/login.c')
-rw-r--r-- | login-utils/login.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/login-utils/login.c b/login-utils/login.c index fdc8078dd..1550388c4 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) |