2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

Use TCSAFLUSH not TCSADRAIN when disabling echo

A long time ago this was changed from TCSAFLUSH to TCSADRAIN due
to some systems having problems with TCSAFLUSH.  That should no
longer be a concern.  Using TCSAFLUSH ensures that password input
that has been received by the kernel, but not yet read by sudo,
will be discarded and not echoed.
This commit is contained in:
Todd C. Miller 2025-05-22 08:38:29 -06:00
parent 82ebb1eaa9
commit 77fe6ae51e
4 changed files with 14 additions and 5 deletions

View File

@ -342,7 +342,8 @@ extern int (*sudo_printf)(int msg_type, const char * restrict fmt, ...);
sudo_dso_public bool sudo_isatty_v1(int fd, struct stat *sbp); sudo_dso_public bool sudo_isatty_v1(int fd, struct stat *sbp);
#define sudo_isatty(_a, _b) sudo_isatty_v1((_a), (_b)) #define sudo_isatty(_a, _b) sudo_isatty_v1((_a), (_b))
sudo_dso_public bool sudo_term_cbreak_v1(int fd); sudo_dso_public bool sudo_term_cbreak_v1(int fd);
#define sudo_term_cbreak(_a) sudo_term_cbreak_v1((_a)) sudo_dso_public bool sudo_term_cbreak_v2(int fd, bool flush);
#define sudo_term_cbreak(_a, _b) sudo_term_cbreak_v2((_a), (_b))
sudo_dso_public bool sudo_term_copy_v1(int src, int dst); sudo_dso_public bool sudo_term_copy_v1(int src, int dst);
#define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b)) #define sudo_term_copy(_a, _b) sudo_term_copy_v1((_a), (_b))
sudo_dso_public bool sudo_term_noecho_v1(int fd); sudo_dso_public bool sudo_term_noecho_v1(int fd);

View File

@ -244,7 +244,7 @@ sudo_term_noecho_v1(int fd)
#ifdef VSTATUS #ifdef VSTATUS
term.c_cc[VSTATUS] = _POSIX_VDISABLE; term.c_cc[VSTATUS] = _POSIX_VDISABLE;
#endif #endif
if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == -1) { if (tcsetattr_nobg(fd, TCSASOFT|TCSAFLUSH, &term) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"%s: tcsetattr(%d)", __func__, fd); "%s: tcsetattr(%d)", __func__, fd);
goto unlock; goto unlock;
@ -358,8 +358,9 @@ unlock:
* Returns true on success or false on failure. * Returns true on success or false on failure.
*/ */
bool bool
sudo_term_cbreak_v1(int fd) sudo_term_cbreak_v2(int fd, bool flush)
{ {
const int flags = flush ? (TCSASOFT|TCSAFLUSH) : (TCSASOFT|TCSADRAIN);
struct termios term = { 0 }; struct termios term = { 0 };
bool ret = false; bool ret = false;
debug_decl(sudo_term_cbreak, SUDO_DEBUG_UTIL); debug_decl(sudo_term_cbreak, SUDO_DEBUG_UTIL);
@ -382,7 +383,7 @@ sudo_term_cbreak_v1(int fd)
#ifdef VSTATUS #ifdef VSTATUS
term.c_cc[VSTATUS] = _POSIX_VDISABLE; term.c_cc[VSTATUS] = _POSIX_VDISABLE;
#endif #endif
if (tcsetattr_nobg(fd, TCSASOFT|TCSADRAIN, &term) == -1) { if (tcsetattr_nobg(fd, flags, &term) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
"%s: tcsetattr(%d)", __func__, fd); "%s: tcsetattr(%d)", __func__, fd);
goto unlock; goto unlock;
@ -399,6 +400,12 @@ unlock:
debug_return_bool(ret); debug_return_bool(ret);
} }
bool
sudo_term_cbreak_v1(int fd)
{
return sudo_term_cbreak_v2(fd, false);
}
/* /*
* Copy terminal settings from one descriptor to another. * Copy terminal settings from one descriptor to another.
* We cannot simply copy the struct termios as src and dst may be * We cannot simply copy the struct termios as src and dst may be

View File

@ -159,6 +159,7 @@ sudo_strtomode_v1
sudo_strtomode_v2 sudo_strtomode_v2
sudo_strtonum sudo_strtonum
sudo_term_cbreak_v1 sudo_term_cbreak_v1
sudo_term_cbreak_v2
sudo_term_copy_v1 sudo_term_copy_v1
sudo_term_eof sudo_term_eof
sudo_term_erase sudo_term_erase

View File

@ -185,7 +185,7 @@ restart:
if (!ISSET(flags, TGP_ECHO)) { if (!ISSET(flags, TGP_ECHO)) {
for (;;) { for (;;) {
if (ISSET(flags, TGP_MASK)) if (ISSET(flags, TGP_MASK))
neednl = feedback = sudo_term_cbreak(input); neednl = feedback = sudo_term_cbreak(input, true);
else else
neednl = sudo_term_noecho(input); neednl = sudo_term_noecho(input);
if (neednl || errno != EINTR) if (neednl || errno != EINTR)