From 3f13d198679437002df2dd0777a3bca879c0061c Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Thu, 21 Sep 2023 20:25:55 +0200 Subject: [PATCH] login: prevent undefined ioctl and tcsetattr calls Do not call tcsetattr if tcgetattr fails, because the content of tt and ttt is undefined in that case. Also do not just warn if ioctl fails, but also avoid calling it again after tty has been re-opened. I've solved this by setting struct variables to values which cannot be valid at this point. If they do have these exact values, then the calls will be prevented. Signed-off-by: Tobias Stoeckmann --- login-utils/login.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/login-utils/login.c b/login-utils/login.c index 31a7adb07b..544eab5aaa 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -177,9 +177,10 @@ static void __attribute__((__noreturn__)) struct termios ti; /* reset echo */ - tcgetattr(0, &ti); - ti.c_lflag |= ECHO; - tcsetattr(0, TCSANOW, &ti); + if (tcgetattr(0, &ti) >= 0) { + ti.c_lflag |= ECHO; + tcsetattr(0, TCSANOW, &ti); + } _exit(EXIT_SUCCESS); /* %% */ } @@ -513,8 +514,8 @@ static void chown_tty(struct login_context *cxt) static void init_tty(struct login_context *cxt) { struct stat st; - struct termios tt, ttt; - struct winsize ws; + struct termios tt, ttt = { 0 }; + struct winsize ws = { 0 }; int fd; cxt->tty_mode = (mode_t) getlogindefs_num("TTYPERM", TTY_MODE); @@ -549,13 +550,18 @@ static void init_tty(struct login_context *cxt) /* The TTY size might be reset to 0x0 by the kernel when we close the stdin/stdout/stderr file * descriptors so let's save the size now so we can reapply it later */ - memset(&ws, 0, sizeof(struct winsize)); - if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) { syslog(LOG_WARNING, _("TIOCGWINSZ ioctl failed: %m")); + ws.ws_row = 0; + ws.ws_col = 0; + } - tcgetattr(fd, &tt); - ttt = tt; - ttt.c_cflag &= ~HUPCL; + if (tcgetattr(fd, &tt) >= 0) { + ttt = tt; + ttt.c_cflag &= ~HUPCL; + } else { + ttt.c_cflag = HUPCL; + } if ((fchown(fd, 0, 0) || fchmod(fd, cxt->tty_mode)) && errno != EROFS) { @@ -565,7 +571,8 @@ static void init_tty(struct login_context *cxt) } /* Kill processes left on this tty */ - tcsetattr(fd, TCSANOW, &ttt); + if ((ttt.c_cflag & HUPCL) == 0) + tcsetattr(fd, TCSANOW, &ttt); /* * Let's close file descriptors before vhangup @@ -583,7 +590,8 @@ static void init_tty(struct login_context *cxt) open_tty(cxt->tty_path); /* restore tty modes */ - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt); + if ((ttt.c_cflag & HUPCL) == 0) + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt); /* Restore tty size */ if ((ws.ws_row > 0 || ws.ws_col > 0) -- 2.47.2