[gnome-continuous-yocto/gnomeostree-3.22-krogoth: 41/246] sudo: CVE-2015-8239



commit 016df260e531c4e8209b3b3a79697c2055f8e0ce
Author: Sona Sarmadi <sona sarmadi enea com>
Date:   Tue Aug 9 13:04:41 2016 +0200

    sudo: CVE-2015-8239
    
    Fixes race condition when checking digests in sudoers.
    
    Reference:
    http://seclists.org/oss-sec/2015/q4/327
    
    Reference to upstream fixes:
    https://www.sudo.ws/repos/sudo/raw-rev/397722cdd7ec
    https://www.sudo.ws/repos/sudo/raw-rev/0cd3cc8fa195
    
    (From OE-Core rev: 3564999bd987b08188e2e0eead59a49bebbc5e32)
    
    Signed-off-by: Sona Sarmadi <sona sarmadi enea com>
    Signed-off-by: Armin Kuster <akuster808 gmail com>
    Signed-off-by: Richard Purdie <richard purdie linuxfoundation org>

 .../sudo/sudo/CVE-2015-8239-1.patch                |  699 ++++++++++++++++++++
 .../sudo/sudo/CVE-2015-8239-2.patch                |   45 ++
 meta/recipes-extended/sudo/sudo_1.8.15.bb          |    2 +
 3 files changed, 746 insertions(+), 0 deletions(-)
---
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2015-8239-1.patch 
b/meta/recipes-extended/sudo/sudo/CVE-2015-8239-1.patch
new file mode 100644
index 0000000..582c0bf
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2015-8239-1.patch
@@ -0,0 +1,699 @@
+# HG changeset patch
+# User Todd C. Miller <Todd Miller courtesan com>
+# Date 1451928918 25200
+# Node ID 397722cdd7eceef0aec561909418215e275ccd44
+# Parent  33272418bb10ee780184dbd2d966a4e5c3bc597e
+Add support for using fexecve() if supported on commands that are
+checksummed.
+
+Reference to upstream patch:
+https://www.sudo.ws/repos/sudo/rev/397722cdd7ec
+
+CVE: CVE-2015-8239
+Upstream-Status: Backport
+Signed-off-by: Sona Sarmadi <sona sarmadi enea com>
+---
+diff -ruN a/configure b/configure
+--- a/configure        2015-11-01 00:35:24.000000000 +0100
++++ b/configure        2016-08-08 12:56:03.441681854 +0200
+@@ -2650,6 +2650,7 @@
+ as_fn_append ac_header_list " sys/select.h"
+ as_fn_append ac_header_list " sys/stropts.h"
+ as_fn_append ac_header_list " sys/sysmacros.h"
++as_fn_append ac_func_list " fexecve"
+ as_fn_append ac_func_list " killpg"
+ as_fn_append ac_func_list " nl_langinfo"
+ as_fn_append ac_func_list " strftime"
+@@ -18078,6 +18079,8 @@
+ 
+ 
+ 
++
++
+ for ac_func in getgrouplist
+ do :
+   ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
+@@ -19903,8 +19906,8 @@
+ fi
+ done
+ 
+-    # Check for fexecve, posix_spawn, and posix_spawnp
+-    for ac_func in fexecve posix_spawn posix_spawnp
++    # Check for posix_spawn, and posix_spawnp
++    for ac_func in posix_spawn posix_spawnp
+ do :
+   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+diff -ruN a/configure.ac b/configure.ac
+--- a/configure.ac     2016-08-08 12:55:08.781888802 +0200
++++ b/configure.ac     2016-08-08 12:56:03.445681547 +0200
+@@ -1,7 +1,7 @@
+ dnl
+ dnl Use the top-level autogen.sh script to generate configure and config.h.in
+ dnl
+-dnl Copyright (c) 1994-1996,1998-2015 Todd C. Miller <Todd Miller courtesan com>
++dnl Copyright (c) 1994-1996,1998-2016 Todd C. Miller <Todd Miller courtesan com>
+ dnl
+ AC_PREREQ([2.59])
+ AC_INIT([sudo], [1.8.15], [http://www.sudo.ws/bugs/], [sudo])
+@@ -2384,7 +2384,7 @@
+ dnl Function checks
+ dnl
+ AC_FUNC_GETGROUPS
+-AC_CHECK_FUNCS_ONCE([killpg nl_langinfo strftime pread pwrite openat])
++AC_CHECK_FUNCS_ONCE([fexecve killpg nl_langinfo strftime pread pwrite openat])
+ AC_CHECK_FUNCS([getgrouplist], [], [
+     case "$host_os" in
+     aix*)
+@@ -2676,8 +2676,8 @@
+ if test X"$with_noexec" != X"no"; then
+     # Check for non-standard exec functions
+     AC_CHECK_FUNCS([exect execvP execvpe])
+-    # Check for fexecve, posix_spawn, and posix_spawnp
+-    AC_CHECK_FUNCS([fexecve posix_spawn posix_spawnp])
++    # Check for posix_spawn, and posix_spawnp
++    AC_CHECK_FUNCS([posix_spawn posix_spawnp])
+ fi
+ 
+ dnl
+diff -ruN a/doc/sudoers.cat b/doc/sudoers.cat
+--- a/doc/sudoers.cat  2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudoers.cat  2016-08-08 12:56:03.445681547 +0200
+@@ -410,6 +410,13 @@
+      $ openssl dgst -binary -sha224 /bin/ls | openssl base64
+      EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
+ 
++     Warning, if the user has write access to the command itself (directly or
++     via a sudo command), it may be possible for the user to replace the
++     command after the digest check has been performed but before the command
++     is executed.  A similar race condition exists on systems that lack the
++     fexecve(2) system call when the directory in which the command is located
++     is writable by the user.
++
+      Command digests are only supported by version 1.8.7 or higher.
+ 
+    DDeeffaauullttss
+diff -ruN a/doc/sudoers.man.in b/doc/sudoers.man.in
+--- a/doc/sudoers.man.in       2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudoers.man.in       2016-08-08 12:56:03.445681547 +0200
+@@ -1,7 +1,7 @@
+ .\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER!
+ .\" IT IS GENERATED AUTOMATICALLY FROM sudoers.mdoc.in
+ .\"
+-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2015
++.\" Copyright (c) 1994-1996, 1998-2005, 2007-2016
+ .\"   Todd C. Miller <Todd Miller courtesan com>
+ .\"
+ .\" Permission to use, copy, modify, and distribute this software for any
+@@ -877,6 +877,15 @@
+ .RE
+ .fi
+ .PP
++Warning, if the user has write access to the command itself (directly or via a
++ \fBsudo\fR
++command), it may be possible for the user to replace the command after the
++digest check has been performed but before the command is executed.
++A similar race condition exists on systems that lack the
++fexecve(2)
++system call when the directory in which the command is located
++is writable by the user.
++ .PP
+ Command digests are only supported by version 1.8.7 or higher.
+ .SS "Defaults"
+ Certain configuration options may be changed from their default
+diff -ruN a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
+--- a/doc/sudoers.mdoc.in      2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudoers.mdoc.in      2016-08-08 12:56:03.449681239 +0200
+@@ -1,5 +1,5 @@
+ .\"
+-.\" Copyright (c) 1994-1996, 1998-2005, 2007-2015
++.\" Copyright (c) 1994-1996, 1998-2005, 2007-2016
+ .\"   Todd C. Miller <Todd Miller courtesan com>
+ .\"
+ .\" Permission to use, copy, modify, and distribute this software for any
+@@ -834,6 +834,15 @@
+ EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
+ .Ed
+ .Pp
++Warning, if the user has write access to the command itself (directly or via a
++ .Nm sudo
++command), it may be possible for the user to replace the command after the
++digest check has been performed but before the command is executed.
++A similar race condition exists on systems that lack the
++.Xr fexecve 2
++system call when the directory in which the command is located
++is writable by the user.
++ .Pp
+ Command digests are only supported by version 1.8.7 or higher.
+ .Ss Defaults
+ Certain configuration options may be changed from their default
+diff -ruN a/doc/sudo_plugin.cat b/doc/sudo_plugin.cat
+--- a/doc/sudo_plugin.cat      2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudo_plugin.cat      2016-08-08 12:56:03.449681239 +0200
+@@ -499,6 +499,11 @@
+                        This setting has no effect unless I/O logging is
+                        enabled or _u_s_e___p_t_y is enabled.
+ 
++                 execfd=number
++                       If specified, ssuuddoo will use the fexecve(2) system call
++                       to execute the command instead of execve(2).  The
++                       specified _n_u_m_b_e_r must refer to an open file descriptor.
++
+                  iolog_compress=bool
+                        Set to true if the I/O logging plugins, if any, should
+                        compress the log data.  This is a hint to the I/O
+@@ -1505,6 +1510,9 @@
+            it supports plugin API version 1.8 or higher to receive a
+            conversation function pointer that supports this argument.
+ 
++     Version 1.9 (sudo 1.8.16)
++           The _e_x_e_c_f_d entry was added to the command_info list.
++
+ SSEEEE AALLSSOO
+      sudo.conf(4), sudoers(4), sudo(1m)
+ 
+diff -ruN a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in
+--- a/doc/sudo_plugin.man.in   2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudo_plugin.man.in   2016-08-08 12:56:03.449681239 +0200
+@@ -1,7 +1,7 @@
+ .\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER!
+ .\" IT IS GENERATED AUTOMATICALLY FROM sudo_plugin.mdoc.in
+ .\"
+-.\" Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++.\" Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -881,6 +881,17 @@
+ \fIuse_pty\fR
+ is enabled.
+ .TP 6n
++execfd=number
++If specified,
++\fBsudo\fR
++will use the
++fexecve(2)
++system call to execute the command instead of
++execve(2).
++The specified
++\fInumber\fR
++must refer to an open file descriptor.
++.TP 6n
+ iolog_compress=bool
+ Set to true if the I/O logging plugins, if any, should compress the
+ log data.
+@@ -2703,6 +2714,13 @@
+ definition has been updated to match.
+ The plugin must specify that it supports plugin API version 1.8 or higher
+ to receive a conversation function pointer that supports this argument.
++.TP 6n
++Version 1.9 (sudo 1.8.16)
++The
++\fIexecfd\fR
++entry was added to the
++\fRcommand_info\fR
++list.
+ .SH "SEE ALSO"
+ sudo.conf(@mansectform@),
+ sudoers(@mansectform@),
+diff -ruN a/doc/sudo_plugin.mdoc.in b/doc/sudo_plugin.mdoc.in
+--- a/doc/sudo_plugin.mdoc.in  2016-08-08 12:55:08.781888802 +0200
++++ b/doc/sudo_plugin.mdoc.in  2016-08-08 12:56:03.453680931 +0200
+@@ -1,5 +1,5 @@
+ .\"
+-.\" Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++.\" Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -784,6 +784,16 @@
+ This setting has no effect unless I/O logging is enabled or
+ .Em use_pty
+ is enabled.
++.It execfd=number
++If specified,
++.Nm sudo
++will use the
++.Xr fexecve 2
++system call to execute the command instead of
++.Xr execve 2 .
++The specified
++.Em number
++must refer to an open file descriptor.
+ .It iolog_compress=bool
+ Set to true if the I/O logging plugins, if any, should compress the
+ log data.
+@@ -2367,6 +2377,12 @@
+ definition has been updated to match.
+ The plugin must specify that it supports plugin API version 1.8 or higher
+ to receive a conversation function pointer that supports this argument.
++.It Version 1.9 (sudo 1.8.16)
++The
++.Em execfd
++entry was added to the
++.Li command_info
++list.
+ .El
+ .Sh SEE ALSO
+ .Xr sudo.conf @mansectform@ ,
+diff -ruN a/include/sudo_plugin.h b/include/sudo_plugin.h
+--- a/include/sudo_plugin.h    2016-08-08 12:55:08.781888802 +0200
++++ b/include/sudo_plugin.h    2016-08-08 12:56:03.453680931 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -19,7 +19,7 @@
+ 
+ /* API version major/minor */
+ #define SUDO_API_VERSION_MAJOR 1
+-#define SUDO_API_VERSION_MINOR 8
++#define SUDO_API_VERSION_MINOR 9
+ #define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
+ #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
+ 
+diff -ruN a/plugins/sudoers/match.c b/plugins/sudoers/match.c
+--- a/plugins/sudoers/match.c  2016-08-08 12:55:08.781888802 +0200
++++ b/plugins/sudoers/match.c  2016-08-08 12:56:03.453680931 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 1998-2005, 2007-2015
++ * Copyright (c) 1996, 1998-2005, 2007-2016
+  *    Todd C. Miller <Todd Miller courtesan com>
+  *
+  * Permission to use, copy, modify, and distribute this software for any
+@@ -55,6 +55,7 @@
+ # include <netdb.h>
+ #endif /* HAVE_NETGROUP_H */
+ #include <dirent.h>
++#include <fcntl.h>
+ #include <pwd.h>
+ #include <grp.h>
+ #include <errno.h>
+@@ -583,17 +584,18 @@
+ };
+ 
+ static bool
+-digest_matches(const char *file, const struct sudo_digest *sd)
++digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
+ {
+     unsigned char file_digest[SHA512_DIGEST_LENGTH];
+     unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];
+     unsigned char buf[32 * 1024];
+     struct digest_function *func = NULL;
++    bool first = true;
++    bool is_script = false;
+     size_t nread;
+     SHA2_CTX ctx;
+     FILE *fp;
+     unsigned int i;
+-    int h;
+     debug_decl(digest_matches, SUDOERS_DEBUG_MATCH)
+ 
+     for (i = 0; digest_functions[i].digest_name != NULL; i++) {
+@@ -609,7 +611,7 @@
+     if (strlen(sd->digest_str) == func->digest_len * 2) {
+       /* Convert the command digest from ascii hex to binary. */
+       for (i = 0; i < func->digest_len; i++) {
+-          h = hexchar(&sd->digest_str[i + i]);
++          const int h = hexchar(&sd->digest_str[i + i]);
+           if (h == -1)
+               goto bad_format;
+           sudoers_digest[i] = (unsigned char)h;
+@@ -633,6 +635,12 @@
+ 
+     func->init(&ctx);
+     while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) {
++      /* Check for #! cookie and set is_script. */
++      if (first) {
++          first = false;
++          if (nread >= 2 && buf[0] == '#' && buf[1] == '!')
++              is_script = true;
++      }
+       func->update(&ctx, buf, nread);
+     }
+     if (ferror(fp)) {
+@@ -640,15 +648,36 @@
+       fclose(fp);
+       debug_return_bool(false);
+     }
+-    fclose(fp);
+     func->final(file_digest, &ctx);
+ 
+-    if (memcmp(file_digest, sudoers_digest, func->digest_len) == 0)
+-      debug_return_bool(true);
+-    sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
+-      "%s digest mismatch for %s, expecting %s",
+-      func->digest_name, file, sd->digest_str);
+-    debug_return_bool(false);
++    if (memcmp(file_digest, sudoers_digest, func->digest_len) != 0) {
++      fclose(fp);
++      sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
++          "%s digest mismatch for %s, expecting %s",
++          func->digest_name, file, sd->digest_str);
++      debug_return_bool(false);
++    }
++
++#ifdef HAVE_FEXECVE
++    /*
++     * On systems with fexecve(2) we can use that to execute the
++     * matching command even when the directory is writable.
++     */
++    if ((*fd = dup(fileno(fp))) == -1) {
++      sudo_debug_printf(SUDO_DEBUG_INFO, "unable to dup %s: %s",
++          file, strerror(errno));
++      fclose(fp);
++      debug_return_bool(false);
++    }
++    /*
++     * Shell scripts go through namei twice and so we can't set the close
++     * on exec flag on the fd for fexecve(2).
++     */
++    if (!is_script)
++      fcntl(*fd, F_SETFD, FD_CLOEXEC);
++#endif /* HAVE_FEXECVE */
++    fclose(fp);
++    debug_return_bool(true);
+ bad_format:
+     sudo_warnx(U_("digest for %s (%s) is not in %s form"), file,
+       sd->digest_str, func->digest_name);
+@@ -690,7 +719,11 @@
+       debug_return_bool(false);
+     if (!command_args_match(sudoers_cmnd, sudoers_args))
+       debug_return_bool(false);
+-    if (digest != NULL && !digest_matches(sudoers_cmnd, digest)) {
++    if (cmnd_fd != -1) {
++      close(cmnd_fd);
++      cmnd_fd = -1;
++    }
++    if (digest != NULL && !digest_matches(sudoers_cmnd, digest, &cmnd_fd)) {
+       /* XXX - log functions not available but we should log very loudly */
+       debug_return_bool(false);
+     }
+diff -ruN a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
+--- a/plugins/sudoers/policy.c 2016-08-08 12:55:08.781888802 +0200
++++ b/plugins/sudoers/policy.c 2016-08-08 12:56:03.457680623 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2010-2016 Todd C. Miller <Todd Miller 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
+@@ -371,6 +371,9 @@
+     user_umask = umask(SUDO_UMASK);
+     umask(user_umask);
+ 
++    /* Some systems support fexecve() which we use for digest matches. */
++    cmnd_fd = -1;
++
+     /* Dump settings and user info (XXX - plugin args) */
+     for (cur = info->settings; *cur != NULL; cur++)
+       sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
+@@ -545,6 +548,16 @@
+       if (asprintf(&command_info[info_len++], "umask=0%o", (unsigned int)cmnd_umask) == -1)
+           goto oom;
+     }
++    if (cmnd_fd != -1) {
++      if (sudo_version < SUDO_API_MKVERSION(1, 9)) {
++          /* execfd only supported by plugin API 1.9 and higher */
++          close(cmnd_fd);
++          cmnd_fd = -1;
++      } else {
++          if (asprintf(&command_info[info_len++], "execfd=%d", cmnd_fd) == -1)
++              goto oom;
++      }
++    }
+ #ifdef HAVE_LOGIN_CAP_H
+     if (def_use_loginclass) {
+       if ((command_info[info_len++] = sudo_new_key_val("login_class", login_class)) == NULL)
+diff -ruN a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
+--- a/plugins/sudoers/sudoers.h        2016-08-08 12:55:08.781888802 +0200
++++ b/plugins/sudoers/sudoers.h        2016-08-08 12:56:03.457680623 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1993-1996, 1998-2005, 2007-2015
++ * Copyright (c) 1993-1996, 1998-2005, 2007-2016
+  *    Todd C. Miller <Todd Miller courtesan com>
+  *
+  * Permission to use, copy, modify, and distribute this software for any
+@@ -90,6 +90,7 @@
+     const char *cwd;
+     char *iolog_file;
+     GETGROUPS_T *gids;
++    int   execfd;
+     int   ngids;
+     int   closefrom;
+     int   lines;
+@@ -197,6 +198,7 @@
+ #define user_srunhost         (sudo_user.srunhost)
+ #define user_ccname           (sudo_user.krb5_ccname)
+ #define safe_cmnd             (sudo_user.cmnd_safe)
++#define cmnd_fd                       (sudo_user.execfd)
+ #define login_class           (sudo_user.class_name)
+ #define runas_pw              (sudo_user._runas_pw)
+ #define runas_gr              (sudo_user._runas_gr)
+diff -ruN a/src/exec.c b/src/exec.c
+--- a/src/exec.c       2016-08-08 12:55:08.781888802 +0200
++++ b/src/exec.c       2016-08-08 12:56:03.457680623 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -176,13 +176,13 @@
+       }
+ #ifdef HAVE_SELINUX
+       if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+-          selinux_execve(details->command, details->argv, details->envp,
+-              ISSET(details->flags, CD_NOEXEC));
++          selinux_execve(details->execfd, details->command, details->argv,
++              details->envp, ISSET(details->flags, CD_NOEXEC));
+       } else
+ #endif
+       {
+-          sudo_execve(details->command, details->argv, details->envp,
+-              ISSET(details->flags, CD_NOEXEC));
++          sudo_execve(details->execfd, details->command, details->argv,
++              details->envp, ISSET(details->flags, CD_NOEXEC));
+       }
+     }
+     cstat->type = CMD_ERRNO;
+diff -ruN a/src/exec_common.c b/src/exec_common.c
+--- a/src/exec_common.c        2016-08-08 12:55:08.781888802 +0200
++++ b/src/exec_common.c        2016-08-08 12:56:03.457680623 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -134,14 +134,19 @@
+  * ala execvp(3) if we get ENOEXEC.
+  */
+ int
+-sudo_execve(const char *path, char *const argv[], char *const envp[], bool noexec)
++sudo_execve(int fd, const char *path, char *const argv[], char *const envp[], bool noexec)
+ {
+     /* Modify the environment as needed to disable further execve(). */
+     if (noexec)
+       envp = disable_execute(envp);
+ 
+-    execve(path, argv, envp);
+-    if (errno == ENOEXEC) {
++#ifdef HAVE_FEXECVE
++    if (fd != -1)
++           fexecve(fd, argv, envp);
++    else
++#endif
++           execve(path, argv, envp);
++    if (fd == -1 && errno == ENOEXEC) {
+       int argc;
+       char **nargv;
+ 
+diff -ruN a/src/selinux.c b/src/selinux.c
+--- a/src/selinux.c    2016-08-08 12:55:08.781888802 +0200
++++ b/src/selinux.c    2016-08-08 12:56:03.461680315 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2009-2016 Todd C. Miller <Todd Miller courtesan com>
+  * Copyright (c) 2008 Dan Walsh <dwalsh redhat com>
+  *
+  * Borrowed heavily from newrole source code
+@@ -373,7 +373,7 @@
+ }
+ 
+ void
+-selinux_execve(const char *path, char *const argv[], char *const envp[],
++selinux_execve(int fd, const char *path, char *const argv[], char *const envp[],
+     int noexec)
+ {
+     char **nargv;
+@@ -409,6 +409,8 @@
+      */
+     for (argc = 0; argv[argc] != NULL; argc++)
+       continue;
++    if (fd != -1)
++      argc++;
+     nargv = reallocarray(NULL, argc + 2, sizeof(char *));
+     if (nargv == NULL) {
+       sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+@@ -418,11 +420,16 @@
+       nargv[0] = *argv[0] == '-' ? "-sesh-noexec" : "sesh-noexec";
+     else
+       nargv[0] = *argv[0] == '-' ? "-sesh" : "sesh";
+-    nargv[1] = (char *)path;
+-    memcpy(&nargv[2], &argv[1], argc * sizeof(char *)); /* copies NULL */
++    argc = 1;
++    if (fd != -1 && asprintf(&nargv[argc++], "--execfd=%d", fd) == -1) {
++      sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
++      debug_return;
++    }
++    nargv[argc] = (char *)path;
++    memcpy(&nargv[argc + 1], &argv[argc], argc * sizeof(char *)); /* copies NULL */
+ 
+     /* sesh will handle noexec for us. */
+-    sudo_execve(sesh, nargv, envp, false);
++    sudo_execve(-1, sesh, nargv, envp, false);
+     serrno = errno;
+     free(nargv);
+     errno = serrno;
+diff -ruN a/src/sesh.c b/src/sesh.c
+--- a/src/sesh.c       2016-08-08 12:55:08.781888802 +0200
++++ b/src/sesh.c       2016-08-08 12:56:03.461680315 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2008, 2010-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2008, 2010-2016 Todd C. Miller <Todd Miller 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
+@@ -87,6 +87,7 @@
+     } else {
+       bool login_shell, noexec = false;
+       char *cp, *cmnd;
++      int fd = -1;
+ 
+       /* If the first char of argv[0] is '-', we are running a login shell. */
+       login_shell = argv[0][0] == '-';
+@@ -95,6 +96,18 @@
+       if ((cp = strrchr(argv[0], '-')) != NULL && cp != argv[0])
+           noexec = strcmp(cp, "-noexec") == 0;
+ 
++      /* If argv[1] is --execfd=%d, extract the fd to exec with. */
++      if (strncmp(argv[1], "--execfd=", 9) == 0) {
++          const char *errstr;
++
++          cp = argv[1] + 9;
++          fd = strtonum(cp, 0, INT_MAX, &errstr);
++          if (errstr != NULL)
++              sudo_fatalx(U_("invalid file descriptor number: %s"), cp);
++          argv++;
++          argc--;
++      }
++
+       /* Shift argv and make a copy of the command to execute. */
+       argv++;
+       argc--;
+@@ -108,7 +121,7 @@
+           *cp = '-';
+           argv[0] = cp;
+       }
+-      sudo_execve(cmnd, argv, envp, noexec);
++      sudo_execve(fd, cmnd, argv, envp, noexec);
+       sudo_warn(U_("unable to execute %s"), cmnd);
+       ret = SESH_ERR_FAILURE;
+     }
+diff -ruN a/src/sudo.c b/src/sudo.c
+--- a/src/sudo.c       2016-08-08 12:55:08.781888802 +0200
++++ b/src/sudo.c       2016-08-08 12:56:03.461680315 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2009-2015 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2009-2016 Todd C. Miller <Todd Miller 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
+@@ -585,6 +585,7 @@
+ 
+     memset(details, 0, sizeof(*details));
+     details->closefrom = -1;
++    details->execfd = -1;
+     TAILQ_INIT(&details->preserved_fds);
+ 
+ #define SET_STRING(s, n) \
+@@ -615,6 +616,21 @@
+                       SET(details->flags, CD_EXEC_BG);
+                   break;
+               }
++              if (strncmp("execfd=", info[i], sizeof("execfd=") - 1) == 0) {
++                  cp = info[i] + sizeof("execfd=") - 1;
++                  details->execfd = strtonum(cp, 0, INT_MAX, &errstr);
++                  if (errstr != NULL)
++                      sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
++#ifdef HAVE_FEXECVE
++                  /* Must keep fd open during exec. */
++                  add_preserved_fd(&details->preserved_fds, details->execfd);
++#else
++                  /* Plugin thinks we support fexecve() but we don't. */
++                  fcntl(details->execfd, F_SETFD, FD_CLOEXEC);
++                  details->execfd = -1;
++#endif
++                  break;
++              }
+               break;
+           case 'l':
+               SET_STRING("login_class=", login_class)
+diff -ruN a/src/sudo_exec.h b/src/sudo_exec.h
+--- a/src/sudo_exec.h  2016-08-08 12:55:08.781888802 +0200
++++ b/src/sudo_exec.h  2016-08-08 13:04:19.127533565 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2013 Todd C. Miller <Todd Miller courtesan com>
++ * Copyright (c) 2010-2016 Todd C. Miller <Todd Miller 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
+@@ -74,7 +74,7 @@
+ 
+ /* exec.c */
+ struct sudo_event_base;
+-int sudo_execve(const char *path, char *const argv[], char *const envp[], bool noexec);
++int sudo_execve(int fd, const char *path, char *const argv[], char *const envp[], bool noexec);
+ extern volatile pid_t cmnd_pid;
+ 
+ /* exec_pty.c */
+diff -ruN a/src/sudo.h b/src/sudo.h
+--- a/src/sudo.h       2016-08-08 12:55:08.781888802 +0200
++++ b/src/sudo.h       2016-08-08 12:56:03.465680007 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1993-1996, 1998-2005, 2007-2014
++ * Copyright (c) 1993-1996, 1998-2005, 2007-2016
+  *    Todd C. Miller <Todd Miller courtesan com>
+  *
+  * Permission to use, copy, modify, and distribute this software for any
+@@ -149,6 +149,7 @@
+     int ngroups;
+     int closefrom;
+     int flags;
++    int execfd;
+     struct preserved_fd_list preserved_fds;
+     struct passwd *pw;
+     GETGROUPS_T *groups;
+@@ -221,7 +222,7 @@
+ int selinux_restore_tty(void);
+ int selinux_setup(const char *role, const char *type, const char *ttyn,
+     int ttyfd);
+-void selinux_execve(const char *path, char *const argv[], char *const envp[],
++void selinux_execve(int fd, const char *path, char *const argv[], char *envp[],
+     int noexec);
+ 
+ /* solaris.c */
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2015-8239-2.patch 
b/meta/recipes-extended/sudo/sudo/CVE-2015-8239-2.patch
new file mode 100644
index 0000000..6c48e4c
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2015-8239-2.patch
@@ -0,0 +1,45 @@
+
+# HG changeset patch
+# User Todd C. Miller <Todd Miller courtesan com>
+# Date 1452556552 25200
+# Node ID 0cd3cc8fa19565d3f7eb7d960f6ba5da0dec4889
+# Parent  4d2c1761c75245fb88ce397d68bea10afea9c037
+Silence warning in digest_matches() on systems with no fexecve(2).
+
+Reference to upstream patch:
+https://www.sudo.ws/repos/sudo/raw-rev/0cd3cc8fa195
+
+CVE: CVE-2015-8239
+Upstream-Status: Backport
+Signed-off-by: Sona Sarmadi <sona sarmadi enea com>
+---
+diff -r 4d2c1761c752 -r 0cd3cc8fa195 plugins/sudoers/match.c
+--- a/plugins/sudoers/match.c  Mon Jan 11 16:52:52 2016 -0700
++++ b/plugins/sudoers/match.c  Mon Jan 11 16:55:52 2016 -0700
+@@ -590,8 +590,10 @@
+     unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];
+     unsigned char buf[32 * 1024];
+     struct digest_function *func = NULL;
++#ifdef HAVE_FEXECVE
+     bool first = true;
+     bool is_script = false;
++#endif /* HAVE_FEXECVE */
+     size_t nread;
+     SHA2_CTX ctx;
+     FILE *fp;
+@@ -635,12 +637,14 @@
+ 
+     func->init(&ctx);
+     while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) {
++#ifdef HAVE_FEXECVE
+       /* Check for #! cookie and set is_script. */
+       if (first) {
+           first = false;
+           if (nread >= 2 && buf[0] == '#' && buf[1] == '!')
+               is_script = true;
+       }
++#endif /* HAVE_FEXECVE */
+       func->update(&ctx, buf, nread);
+     }
+     if (ferror(fp)) {
+
diff --git a/meta/recipes-extended/sudo/sudo_1.8.15.bb b/meta/recipes-extended/sudo/sudo_1.8.15.bb
index 042043e..a03e2cd 100644
--- a/meta/recipes-extended/sudo/sudo_1.8.15.bb
+++ b/meta/recipes-extended/sudo/sudo_1.8.15.bb
@@ -3,6 +3,8 @@ require sudo.inc
 SRC_URI = "http://ftp.sudo.ws/sudo/dist/sudo-${PV}.tar.gz \
            ${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
            file://0001-Include-sys-types.h-for-id_t-definition.patch \
+           file://CVE-2015-8239-1.patch \
+           file://CVE-2015-8239-2.patch \
            "
 
 PAM_SRC_URI = "file://sudo.pam"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]