Blame SOURCES/sudo-1.8.29-CVE-2019-18634-part2.patch

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