diff -Nru sudo-1.8.9p5/debian/changelog sudo-1.8.9p5/debian/changelog --- sudo-1.8.9p5/debian/changelog 2017-05-29 09:57:53.000000000 +0000 +++ sudo-1.8.9p5/debian/changelog 2017-06-15 08:03:26.000000000 +0000 @@ -1,3 +1,14 @@ +sudo (1.8.9p5-1ubuntu1.5) trusty-security; urgency=medium + + * SECURITY UPDATE: /proc/self/stat parsing newline confusion + - debian/patches/CVE-2017-1000368.patch: read all lines of + /proc/self/stat + - CVE-2017-1000368 + * debian/patches/avoid_sign_extension_tty_nr.patch: hardening to + ensure sign extension doesn't occur when parsing /proc/self/stat + + -- Steve Beattie Thu, 15 Jun 2017 01:00:23 -0700 + sudo (1.8.9p5-1ubuntu1.4) trusty-security; urgency=medium * SECURITY UPDATE: /proc/self/stat parsing confusion diff -Nru sudo-1.8.9p5/debian/patches/avoid_sign_extension_tty_nr.patch sudo-1.8.9p5/debian/patches/avoid_sign_extension_tty_nr.patch --- sudo-1.8.9p5/debian/patches/avoid_sign_extension_tty_nr.patch 1970-01-01 00:00:00.000000000 +0000 +++ sudo-1.8.9p5/debian/patches/avoid_sign_extension_tty_nr.patch 2017-06-15 08:04:00.000000000 +0000 @@ -0,0 +1,40 @@ +changeset: 10994:c198d1317560 +Author: Todd C. Miller +date: Sat Jun 03 08:45:29 2017 -0600 +files: src/ttyname.c +description: +Avoid sign extension when assigning the value of tty_nr in +/proc/self/stat on Linux. It is an unsigned int value that +is printed as a signed int but dev_t is unsigned long long. +We need to cast to unsigned int before assigning to a dev_t. + + + src/ttyname.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +Index: b/src/ttyname.c +=================================================================== +--- a/src/ttyname.c ++++ b/src/ttyname.c +@@ -451,12 +451,19 @@ get_process_ttyname(void) + if (*ep == ' ') { + *ep = '\0'; + if (++field == 7) { +- dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr); ++ int tty_nr = strtonum(cp, INT_MIN, INT_MAX, &errstr); + if (errstr) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "%s: tty device %s: %s", path, cp, errstr); + } +- if (tdev > 0) { ++ if (tty_nr != 0) { ++ /* ++ * Avoid sign extension when assigning tdev. ++ * tty_nr in /proc/self/stat is printed as a ++ * signed int but the actual device number is an ++ * unsigned int and dev_t is unsigned long long. ++ */ ++ dev_t tdev = (unsigned int)tty_nr; + errno = serrno; + tty = sudo_ttyname_dev(tdev); + goto done; diff -Nru sudo-1.8.9p5/debian/patches/CVE-2017-1000368.patch sudo-1.8.9p5/debian/patches/CVE-2017-1000368.patch --- sudo-1.8.9p5/debian/patches/CVE-2017-1000368.patch 1970-01-01 00:00:00.000000000 +0000 +++ sudo-1.8.9p5/debian/patches/CVE-2017-1000368.patch 2017-06-15 08:03:44.000000000 +0000 @@ -0,0 +1,85 @@ +changeset: 10989:9ad60fe663e5 +parent: 10984:ef737b5d4ed8 +Author: Todd C. Miller +date: Wed May 31 09:14:31 2017 -0600 +files: src/ttyname.c +description: +A command name may also contain newline characters so read +/proc/self/stat until EOF. It is not legal for /proc/self/stat to +contain embedded NUL bytes so treat the file as corrupt if we see +any. With help from Qualys. + +This is not exploitable due to the /dev traversal changes in sudo +1.8.20p1 (thanks Solar!). + +CVE-2017-1000368 + +[Ubuntu note: backported to older sudo -- sbeattie] + + src/ttyname.c | 40 +++++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 13 deletions(-) + +Index: b/src/ttyname.c +=================================================================== +--- a/src/ttyname.c ++++ b/src/ttyname.c +@@ -412,24 +412,37 @@ get_process_ttyname(void) + char * + get_process_ttyname(void) + { +- char path[PATH_MAX], *line = NULL, *tty = NULL; +- size_t linesize = 0; ++ char path[PATH_MAX], *tty = NULL; ++ char *cp, buf[1024]; + int serrno = errno; +- ssize_t len; +- FILE *fp; ++ ssize_t nread; ++ int fd; + debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) + +- /* Try to determine the tty from tty_nr in /proc/pid/stat. */ ++ /* ++ * Try to determine the tty from tty_nr in /proc/pid/stat. ++ * Ignore /proc/pid/stat if it contains embedded NUL bytes. ++ */ + snprintf(path, sizeof(path), "/proc/%u/stat", (unsigned int)getpid()); +- if ((fp = fopen(path, "r")) != NULL) { +- len = getline(&line, &linesize, fp); +- fclose(fp); +- if (len != -1) { ++ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) { ++ cp = buf; ++ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) { ++ if (nread == -1) { ++ if (errno == EAGAIN || errno == EINTR) ++ continue; ++ break; ++ } ++ cp += nread; ++ if (cp >= buf + sizeof(buf)) ++ break; ++ } ++ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) { + /* Field 7 is the tty dev (0 if no tty) +- * Since the process name at field 2 "(comm)" may include spaces, +- * start at the last ')' found. ++ * Since the process name at field 2 "(comm)" may include ++ * whitespace (including newlines), start at the last ')' found. + */ +- char *cp = strrchr(line, ')'); ++ *cp = '\0'; ++ cp = strrchr(buf, ')'); + if (cp != NULL) { + char *ep = cp; + const char *errstr; +@@ -459,7 +472,8 @@ get_process_ttyname(void) + errno = ENOENT; + + done: +- efree(line); ++ if (fd != -1) ++ close(fd); + if (tty == NULL) + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, + "unable to resolve tty via %s", path); diff -Nru sudo-1.8.9p5/debian/patches/series sudo-1.8.9p5/debian/patches/series --- sudo-1.8.9p5/debian/patches/series 2017-05-23 01:17:27.000000000 +0000 +++ sudo-1.8.9p5/debian/patches/series 2017-06-15 07:55:41.000000000 +0000 @@ -6,3 +6,5 @@ CVE-2014-9680.patch bug-1319403.patch CVE-2017-1000367.patch +CVE-2017-1000368.patch +avoid_sign_extension_tty_nr.patch