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

c86b7a
diff -up ./src/tgetpass.c.bla ./src/tgetpass.c
c86b7a
--- ./src/tgetpass.c.bla	2018-08-18 16:10:15.000000000 +0200
c86b7a
+++ ./src/tgetpass.c	2020-02-05 17:15:16.216904891 +0100
c86b7a
@@ -44,11 +44,18 @@
c86b7a
 #include "sudo.h"
c86b7a
 #include "sudo_plugin.h"
c86b7a
 
c86b7a
+enum tgetpass_errval {
c86b7a
+    TGP_ERRVAL_NOERROR,
c86b7a
+    TGP_ERRVAL_TIMEOUT,
c86b7a
+    TGP_ERRVAL_NOPASSWORD,
c86b7a
+    TGP_ERRVAL_READERROR
c86b7a
+};
c86b7a
+
c86b7a
 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);
c86b7a
+static char *getln(int, char *, size_t, int, enum tgetpass_errval *);
c86b7a
 static char *sudo_askpass(const char *, const char *);
c86b7a
 
c86b7a
 static int
c86b7a
@@ -77,6 +84,27 @@ suspend(int signo, struct sudo_conv_call
c86b7a
     debug_return_int(ret);
c86b7a
 }
c86b7a
 
c86b7a
+static void
c86b7a
+tgetpass_display_error(enum tgetpass_errval errval)
c86b7a
+{
c86b7a
+    debug_decl(tgetpass_display_error, SUDO_DEBUG_CONV)
c86b7a
+
c86b7a
+    switch (errval) {
c86b7a
+    case TGP_ERRVAL_NOERROR:
c86b7a
+	break;
c86b7a
+    case TGP_ERRVAL_TIMEOUT:
c86b7a
+	sudo_warnx(U_("timed out reading password"));
c86b7a
+	break;
c86b7a
+    case TGP_ERRVAL_NOPASSWORD:
c86b7a
+	sudo_warnx(U_("no password was provided"));
c86b7a
+	break;
c86b7a
+    case TGP_ERRVAL_READERROR:
c86b7a
+	sudo_warn(U_("unable to read password"));
c86b7a
+	break;
c86b7a
+    }
c86b7a
+    debug_return;
c86b7a
+}
c86b7a
+
c86b7a
 /*
c86b7a
  * Like getpass(3) but with timeout and echo flags.
c86b7a
  */
c86b7a
@@ -90,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
+    enum tgetpass_errval errval;
c86b7a
     debug_decl(tgetpass, SUDO_DEBUG_CONV)
c86b7a
 
c86b7a
     (void) fflush(stdout);
c86b7a
@@ -175,7 +204,7 @@ restart:
c86b7a
 
c86b7a
     if (timeout > 0)
c86b7a
 	alarm(timeout);
c86b7a
-    pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK));
c86b7a
+    pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval);
c86b7a
     alarm(0);
c86b7a
     save_errno = errno;
c86b7a
 
c86b7a
@@ -183,6 +212,7 @@ restart:
c86b7a
 	if (write(output, "\n", 1) == -1)
c86b7a
 	    goto restore;
c86b7a
     }
c86b7a
+    tgetpass_display_error(errval);
c86b7a
 
c86b7a
 restore:
c86b7a
     /* Restore old signal handlers. */
c86b7a
@@ -210,6 +240,8 @@ restore:
c86b7a
     for (i = 0; i < NSIG; i++) {
c86b7a
 	if (signo[i]) {
c86b7a
 	    switch (i) {
c86b7a
+		case SIGALRM:
c86b7a
+		    break;
c86b7a
 		case SIGTSTP:
c86b7a
 		case SIGTTIN:
c86b7a
 		case SIGTTOU:
c86b7a
@@ -239,6 +271,7 @@ sudo_askpass(const char *askpass, const
c86b7a
 {
c86b7a
     static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
c86b7a
     struct sigaction sa, savechld;
c86b7a
+    enum tgetpass_errval errval;
c86b7a
     int pfd[2], status;
c86b7a
     pid_t child;
c86b7a
     debug_decl(sudo_askpass, SUDO_DEBUG_CONV)
c86b7a
@@ -281,9 +314,11 @@ sudo_askpass(const char *askpass, const
c86b7a
 
c86b7a
     /* Get response from child (askpass). */
c86b7a
     (void) close(pfd[1]);
c86b7a
-    pass = getln(pfd[0], buf, sizeof(buf), 0);
c86b7a
+    pass = getln(pfd[0], buf, sizeof(buf), 0, &errval);
c86b7a
     (void) close(pfd[0]);
c86b7a
 
c86b7a
+    tgetpass_display_error(errval);
c86b7a
+
c86b7a
     /* Wait for child to exit. */
c86b7a
     for (;;) {
c86b7a
 	pid_t rv = waitpid(child, &status, 0);
c86b7a
@@ -305,7 +340,8 @@ 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, int feedback,
c86b7a
+      enum tgetpass_errval *errval)
c86b7a
 {
c86b7a
     size_t left = bufsiz;
c86b7a
     ssize_t nr = -1;
c86b7a
@@ -313,7 +349,10 @@ getln(int fd, char *buf, size_t bufsiz,
c86b7a
     char c = '\0';
c86b7a
     debug_decl(getln, SUDO_DEBUG_CONV)
c86b7a
 
c86b7a
+    *errval = TGP_ERRVAL_NOERROR;
c86b7a
+
c86b7a
     if (left == 0) {
c86b7a
+	*errval = TGP_ERRVAL_READERROR;
c86b7a
 	errno = EINVAL;
c86b7a
 	debug_return_str(NULL);		/* sanity */
c86b7a
     }
c86b7a
@@ -354,14 +393,27 @@ getln(int fd, char *buf, size_t bufsiz,
c86b7a
 	}
c86b7a
     }
c86b7a
 
c86b7a
-    debug_return_str_masked(nr == 1 ? buf : NULL);
c86b7a
+    if (nr != 1) {
c86b7a
+	if (nr == 0) {
c86b7a
+	    *errval = TGP_ERRVAL_NOPASSWORD;
c86b7a
+	} else if (nr == -1) {
c86b7a
+	    if (errno == EINTR) {
c86b7a
+		if (signo[SIGALRM] == 1)
c86b7a
+		    *errval = TGP_ERRVAL_TIMEOUT;
c86b7a
+	    } else {
c86b7a
+		*errval = TGP_ERRVAL_READERROR;
c86b7a
+	    }
c86b7a
+	}
c86b7a
+	debug_return_str(NULL);
c86b7a
+    }
c86b7a
+
c86b7a
+    debug_return_str_masked(buf);
c86b7a
 }
c86b7a
 
c86b7a
 static void
c86b7a
 tgetpass_handler(int s)
c86b7a
 {
c86b7a
-    if (s != SIGALRM)
c86b7a
-	signo[s] = 1;
c86b7a
+    signo[s] = 1;
c86b7a
 }
c86b7a
 
c86b7a
 static bool