Hello community,

here is the log from the commit of package sudo for openSUSE:Factory checked in 
at 2017-05-31 21:26:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sudo (Old)
 and      /work/SRC/openSUSE:Factory/.sudo.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sudo"

Wed May 31 21:26:18 2017 rev:86 rq:499850 version:1.8.19p2

Changes:
--------
--- /work/SRC/openSUSE:Factory/sudo/sudo.changes        2017-03-10 
21:05:59.673182349 +0100
+++ /work/SRC/openSUSE:Factory/.sudo.new/sudo.changes   2017-05-31 
21:26:19.337799096 +0200
@@ -1,0 +2,9 @@
+Tue May 30 19:11:42 UTC 2017 - sfl...@suse.de
+
+- Fix a vulnerability in Sudo's get_process_ttyname() leading to 
+  privlage elevation.
+  * sudo-1.8.19p2-CVE-2017-1000367.patch 
+  * CVE-2017-1000367
+  * bsc#1039361
+
+-------------------------------------------------------------------

New:
----
  sudo-1.8.19p2-CVE-2017-1000367.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ sudo.spec ++++++
--- /var/tmp/diff_new_pack.2QeaZM/_old  2017-05-31 21:26:20.221674395 +0200
+++ /var/tmp/diff_new_pack.2QeaZM/_new  2017-05-31 21:26:20.225673831 +0200
@@ -35,6 +35,7 @@
 Patch1:         sudo-sudoers.patch
 Patch2:         sudo-1.8.19p2-decrement_env_len.patch
 Patch3:         sudo-1.8.19p2-dont_overwrite_ret_val.patch
+Patch4:         sudo-1.8.19p2-CVE-2017-1000367.patch
 BuildRequires:  audit-devel
 BuildRequires:  cyrus-sasl-devel
 BuildRequires:  groff
@@ -78,6 +79,7 @@
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
+%patch4 -p1
 
 %build
 %ifarch s390 s390x %sparc

++++++ sudo-1.8.19p2-CVE-2017-1000367.patch ++++++
Index: sudo-1.8.19p2/src/ttyname.c
===================================================================
--- sudo-1.8.19p2.orig/src/ttyname.c
+++ sudo-1.8.19p2/src/ttyname.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Todd C. Miller <todd.mil...@courtesan.com>
+ * Copyright (c) 2012-2017 Todd C. Miller <todd.mil...@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -145,20 +145,22 @@ sudo_ttyname_dev(dev_t tdev, char *name,
 }
 #elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || defined(HAVE_PSTAT_GETPROC) || 
defined(__linux__)
 /*
- * Devices to search before doing a breadth-first scan.
+ * Device nodes and directories to search before searching all of /dev
  */
 static char *search_devs[] = {
     "/dev/console",
-    "/dev/wscons",
-    "/dev/pts/",
-    "/dev/vt/",
-    "/dev/term/",
-    "/dev/zcons/",
+    "/dev/pts/",       /* POSIX pty */
+    "/dev/vt/",                /* Solaris virtual console */
+    "/dev/term/",      /* Solaris serial ports */
+    "/dev/zcons/",     /* Solaris zone console */
+    "/dev/pty/",       /* HP-UX old-style pty */
     NULL
 };
 
+/*
+ * Device nodes to ignore when searching all of /dev
+ */
 static char *ignore_devs[] = {
-    "/dev/fd/",
     "/dev/stdin",
     "/dev/stdout",
     "/dev/stderr",
@@ -166,16 +168,18 @@ static char *ignore_devs[] = {
 };
 
 /*
- * Do a breadth-first scan of dir looking for the specified device.
+ * Do a scan of a directory looking for the specified device.
+ * Does not descend into subdirectories.
  * Returns name on success and NULL on failure, setting errno.
  */
 static char *
-sudo_ttyname_scan(const char *dir, dev_t rdev, bool builtin, char *name, 
size_t namelen)
+sudo_ttyname_scan(const char *dir, dev_t rdev, char *name, size_t namelen)
 {
-    size_t sdlen, num_subdirs = 0, max_subdirs = 0;
-    char pathbuf[PATH_MAX], **subdirs = NULL;
+    size_t sdlen;
+    char pathbuf[PATH_MAX];
     char *ret = NULL;
     struct dirent *dp;
+    struct stat sb;
     unsigned int i;
     DIR *d = NULL;
     debug_decl(sudo_ttyname_scan, SUDO_DEBUG_UTIL)
@@ -183,6 +187,18 @@ sudo_ttyname_scan(const char *dir, dev_t
     if (dir[0] == '\0' || (d = opendir(dir)) == NULL)
        goto done;
 
+    if (fstat(dirfd(d), &sb) == -1) {
+       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+           "unable to fstat %s", dir);
+       goto done;
+    }
+    if ((sb.st_mode & S_IWOTH) != 0) {
+       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+           "ignoring world-writable directory %s", dir);
+       errno = ENOENT;
+       goto done;
+    }
+
     sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
        "scanning for dev %u in %s", (unsigned int)rdev, dir);
 
@@ -220,18 +236,6 @@ sudo_ttyname_scan(const char *dir, dev_t
        }
        if (ignore_devs[i] != NULL)
            continue;
-       if (!builtin) {
-           /* Skip entries in search_devs; we already checked them. */
-           for (i = 0; search_devs[i] != NULL; i++) {
-               len = strlen(search_devs[i]);
-               if (search_devs[i][len - 1] == '/')
-                   len--;
-               if (d_len == len && strncmp(pathbuf, search_devs[i], len) == 0)
-                   break;
-           }
-           if (search_devs[i] != NULL)
-               continue;
-       }
 # if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DTTOIF)
        /*
         * Avoid excessive stat() calls by checking dp->d_type.
@@ -244,39 +248,14 @@ sudo_ttyname_scan(const char *dir, dev_t
                if (stat(pathbuf, &sb) == -1)
                    continue;
                break;
-           case DT_DIR:
-               /* Directory, no need to stat() it. */
-               sb.st_mode = DTTOIF(dp->d_type);
-               sb.st_rdev = 0;         /* quiet ccc-analyzer false positive */
-               break;
            default:
-               /* Not a character device, link or directory, skip it. */
+               /* Not a character device or link, skip it. */
                continue;
        }
 # else
        if (stat(pathbuf, &sb) == -1)
            continue;
 # endif
-       if (S_ISDIR(sb.st_mode)) {
-           if (!builtin) {
-               /* Add to list of subdirs to search. */
-               if (num_subdirs + 1 > max_subdirs) {
-                   char **new_subdirs;
-
-                   new_subdirs = reallocarray(subdirs, max_subdirs + 64,
-                       sizeof(char *));
-                   if (new_subdirs == NULL)
-                       goto done;
-                   subdirs = new_subdirs;
-                   max_subdirs += 64;
-               }
-               subdirs[num_subdirs] = strdup(pathbuf);
-               if (subdirs[num_subdirs] == NULL)
-                   goto done;
-               num_subdirs++;
-           }
-           continue;
-       }
        if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
            sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
                "resolved dev %u as %s", (unsigned int)rdev, pathbuf);
@@ -292,16 +271,9 @@ sudo_ttyname_scan(const char *dir, dev_t
        }
     }
 
-    /* Search subdirs if we didn't find it in the root level. */
-    for (i = 0; ret == NULL && i < num_subdirs; i++)
-       ret = sudo_ttyname_scan(subdirs[i], rdev, false, name, namelen);
-
 done:
     if (d != NULL)
        closedir(d);
-    for (i = 0; i < num_subdirs; i++)
-       free(subdirs[i]);
-    free(subdirs);
     debug_return_str(ret);
 }
 
@@ -320,7 +292,7 @@ sudo_ttyname_dev(dev_t rdev, char *name,
     debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
 
     /*
-     * First check search_devs for common tty devices.
+     * First check search_devs[] for common tty devices.
      */
     for (sd = search_devs; (devname = *sd) != NULL; sd++) {
        len = strlen(devname);
@@ -345,7 +317,7 @@ sudo_ttyname_dev(dev_t rdev, char *name,
                    "comparing dev %u to %s: no", (unsigned int)rdev, buf);
            } else {
                /* Traverse directory */
-               ret = sudo_ttyname_scan(devname, rdev, true, name, namelen);
+               ret = sudo_ttyname_scan(devname, rdev, name, namelen);
                if (ret != NULL || errno == ENOMEM)
                    goto done;
            }
@@ -363,9 +335,9 @@ sudo_ttyname_dev(dev_t rdev, char *name,
     }
 
     /*
-     * Not found?  Do a breadth-first traversal of /dev/.
+     * Not found?  Check all device nodes in /dev.
      */
-    ret = sudo_ttyname_scan(_PATH_DEV, rdev, false, name, namelen);
+    ret = sudo_ttyname_scan(_PATH_DEV, rdev, name, namelen);
 
 done:
     debug_return_str(ret);
@@ -489,28 +461,35 @@ get_process_ttyname(char *name, size_t n
        len = getline(&line, &linesize, fp);
        fclose(fp);
        if (len != -1) {
-           /* Field 7 is the tty dev (0 if no tty) */
-           char *cp = line;
-           char *ep = line;
-           const char *errstr;
-           int field = 0;
-           while (*++ep != '\0') {
-               if (*ep == ' ') {
-                   *ep = '\0';
-                   if (++field == 7) {
-                       dev_t tdev = 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) {
-                           errno = serrno;
-                           ret = sudo_ttyname_dev(tdev, name, namelen);
-                           goto done;
+           /*
+            * 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.
+            */
+           char *cp = strrchr(line, ')');
+           if (cp != NULL) {
+               char *ep = cp;
+               const char *errstr;
+               int field = 1;
+
+               while (*++ep != '\0') {
+                   if (*ep == ' ') {
+                       *ep = '\0';
+                       if (++field == 7) {
+                           dev_t tdev = 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) {
+                               errno = serrno;
+                               ret = sudo_ttyname_dev(tdev, name, namelen);
+                               goto done;
+                           }
+                           break;
                        }
-                       break;
+                       cp = ep + 1;
                    }
-                   cp = ep + 1;
                }
            }
        }



Reply via email to