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>
This commit is contained in:
Sona Sarmadi 2016-08-09 13:04:41 +02:00 committed by Richard Purdie
parent 5d781f41ff
commit 016df260e5
3 changed files with 746 additions and 0 deletions

View File

@ -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 */

View File

@ -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)) {

View File

@ -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"