|
|
168bcc |
diff -up ./src/tgetpass.c.CVE-2019-18634 ./src/tgetpass.c
|
|
|
168bcc |
--- ./src/tgetpass.c.CVE-2019-18634 2020-02-05 17:16:07.601420697 +0100
|
|
|
168bcc |
+++ ./src/tgetpass.c 2020-02-05 17:22:34.206301510 +0100
|
|
|
168bcc |
@@ -55,7 +55,7 @@ static volatile sig_atomic_t signo[NSIG]
|
|
|
168bcc |
|
|
|
168bcc |
static bool tty_present(void);
|
|
|
168bcc |
static void tgetpass_handler(int);
|
|
|
168bcc |
-static char *getln(int, char *, size_t, int, enum tgetpass_errval *);
|
|
|
168bcc |
+static char *getln(int, char *, size_t, bool, enum tgetpass_errval *);
|
|
|
168bcc |
static char *sudo_askpass(const char *, const char *);
|
|
|
168bcc |
|
|
|
168bcc |
static int
|
|
|
168bcc |
@@ -118,6 +118,7 @@ tgetpass(const char *prompt, int timeout
|
|
|
168bcc |
static const char *askpass;
|
|
|
168bcc |
static char buf[SUDO_CONV_REPL_MAX + 1];
|
|
|
168bcc |
int i, input, output, save_errno, neednl = 0, need_restart;
|
|
|
168bcc |
+ bool feedback = ISSET(flags, TGP_MASK);
|
|
|
168bcc |
enum tgetpass_errval errval;
|
|
|
168bcc |
debug_decl(tgetpass, SUDO_DEBUG_CONV)
|
|
|
168bcc |
|
|
|
168bcc |
@@ -165,7 +166,7 @@ restart:
|
|
|
168bcc |
*/
|
|
|
168bcc |
if (!ISSET(flags, TGP_ECHO)) {
|
|
|
168bcc |
for (;;) {
|
|
|
168bcc |
- if (ISSET(flags, TGP_MASK))
|
|
|
168bcc |
+ if (feedback)
|
|
|
168bcc |
neednl = sudo_term_cbreak(input);
|
|
|
168bcc |
else
|
|
|
168bcc |
neednl = sudo_term_noecho(input);
|
|
|
168bcc |
@@ -179,6 +180,9 @@ restart:
|
|
|
168bcc |
}
|
|
|
168bcc |
}
|
|
|
168bcc |
}
|
|
|
168bcc |
+ /* Only use feedback mode when we can disable echo. */
|
|
|
168bcc |
+ if (!neednl)
|
|
|
168bcc |
+ feedback = false;
|
|
|
168bcc |
|
|
|
168bcc |
/*
|
|
|
168bcc |
* Catch signals that would otherwise cause the user to end
|
|
|
168bcc |
@@ -204,7 +208,7 @@ restart:
|
|
|
168bcc |
|
|
|
168bcc |
if (timeout > 0)
|
|
|
168bcc |
alarm(timeout);
|
|
|
168bcc |
- pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval);
|
|
|
168bcc |
+ pass = getln(input, buf, sizeof(buf), feedback, &errval);
|
|
|
168bcc |
alarm(0);
|
|
|
168bcc |
save_errno = errno;
|
|
|
168bcc |
|
|
|
168bcc |
@@ -340,7 +344,7 @@ sudo_askpass(const char *askpass, const
|
|
|
168bcc |
extern int sudo_term_erase, sudo_term_kill;
|
|
|
168bcc |
|
|
|
168bcc |
static char *
|
|
|
168bcc |
-getln(int fd, char *buf, size_t bufsiz, int feedback,
|
|
|
168bcc |
+getln(int fd, char *buf, size_t bufsiz, bool feedback,
|
|
|
168bcc |
enum tgetpass_errval *errval)
|
|
|
168bcc |
{
|
|
|
168bcc |
size_t left = bufsiz;
|
|
|
168bcc |
@@ -366,15 +370,15 @@ getln(int fd, char *buf, size_t bufsiz,
|
|
|
168bcc |
while (cp > buf) {
|
|
|
168bcc |
if (write(fd, "\b \b", 3) == -1)
|
|
|
168bcc |
break;
|
|
|
168bcc |
- --cp;
|
|
|
168bcc |
+ cp--;
|
|
|
168bcc |
}
|
|
|
168bcc |
+ cp = buf;
|
|
|
168bcc |
left = bufsiz;
|
|
|
168bcc |
continue;
|
|
|
168bcc |
} else if (c == sudo_term_erase) {
|
|
|
168bcc |
if (cp > buf) {
|
|
|
168bcc |
- if (write(fd, "\b \b", 3) == -1)
|
|
|
168bcc |
- break;
|
|
|
168bcc |
- --cp;
|
|
|
168bcc |
+ ignore_result(write(fd, "\b \b", 3));
|
|
|
168bcc |
+ cp--;
|
|
|
168bcc |
left++;
|
|
|
168bcc |
}
|
|
|
168bcc |
continue;
|