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