Add support for using fexecve() if supported on commands that are

checksummed.
This commit is contained in:
Todd C. Miller
2016-01-04 10:35:18 -07:00
parent 97e86c74ff
commit b20977d445
19 changed files with 209 additions and 68 deletions

7
configure vendored
View File

@@ -2650,6 +2650,7 @@ as_fn_append ac_header_list " sys/bsdtypes.h"
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 @@ done
for ac_func in getgrouplist
do :
ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
@@ -19903,8 +19906,8 @@ _ACEOF
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"

View File

@@ -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.16], [https://bugzilla.sudo.ws/], [sudo])
@@ -2384,7 +2384,7 @@ dnl
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 @@ dnl
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

View File

@@ -499,6 +499,11 @@ DDEESSCCRRIIPPTTIIOONN
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 @@ PPLLUUGGIINN AAPPII CCHHAANNGGEELLOOGG
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)
@@ -1534,4 +1542,4 @@ DDIISSCCLLAAIIMMEERR
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
complete details.
Sudo 1.8.16 November 20, 2015 Sudo 1.8.16
Sudo 1.8.16 January 4, 2016 Sudo 1.8.16

View File

@@ -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
@@ -16,7 +16,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.TH "SUDO_PLUGIN" "5" "November 20, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.TH "SUDO_PLUGIN" "5" "January 4, 2016" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -881,6 +881,17 @@ This setting has no effect unless I/O logging is enabled or
\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 @@ The
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@),

View File

@@ -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
@@ -14,7 +14,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 20, 2015
.Dd January 4, 2016
.Dt SUDO_PLUGIN @mansectform@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -784,6 +784,16 @@ be a way to enabled or disable it on a per-command basis.
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 @@ The
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@ ,

View File

@@ -408,10 +408,12 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
$ openssl dgst -binary -sha224 /bin/ls | openssl base64
EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
If the user has write access to either the command itself or the
directory in which the command is located (directly or via a ssuuddoo
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.
Warning, if the user has write access to the command itself (directly or
via a ssuuddoo 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.
@@ -2493,4 +2495,4 @@ DDIISSCCLLAAIIMMEERR
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
complete details.
Sudo 1.8.16 December 11, 2015 Sudo 1.8.16
Sudo 1.8.16 January 4, 2015 Sudo 1.8.16

View File

@@ -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
@@ -21,7 +21,7 @@
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\"
.TH "SUDOERS" "5" "December 11, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.TH "SUDOERS" "5" "January 4, 2015" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh
.if n .ad l
.SH "NAME"
@@ -874,12 +874,14 @@ EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
.RE
.fi
.PP
If the user has write access to either the command itself or the
directory in which the command is located (directly or via a
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.
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"

View File

@@ -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
@@ -19,7 +19,7 @@
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\"
.Dd December 11, 2015
.Dd January 4, 2015
.Dt SUDOERS @mansectform@
.Os Sudo @PACKAGE_VERSION@
.Sh NAME
@@ -831,12 +831,14 @@ $ openssl dgst -binary -sha224 /bin/ls | openssl base64
EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
.Ed
.Pp
If the user has write access to either the command itself or the
directory in which the command is located (directly or via a
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.
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

View File

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

View File

@@ -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 struct digest_function {
};
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 @@ digest_matches(const char *file, const struct sudo_digest *sd)
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 @@ digest_matches(const char *file, const struct sudo_digest *sd)
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 @@ digest_matches(const char *file, const struct sudo_digest *sd)
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 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const
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);
}

View File

@@ -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
@@ -377,6 +377,9 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
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);
@@ -551,6 +554,16 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
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)

View File

@@ -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 @@ struct sudo_user {
const char *cwd;
char *iolog_file;
GETGROUPS_T *gids;
int execfd;
int ngids;
int closefrom;
int lines;
@@ -197,6 +198,7 @@ struct sudo_user {
#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)

View File

@@ -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 @@ exec_cmnd(struct command_details *details, struct command_status *cstat,
}
#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;

View File

@@ -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
@@ -179,14 +179,19 @@ disable_execute(char *envp[])
* ala execvp(3) if we get ENOEXEC.
*/
int
sudo_execve(const char *path, char *const argv[], char *envp[], bool noexec)
sudo_execve(int fd, const char *path, char *const argv[], char *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;

View File

@@ -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 @@ done:
}
void
selinux_execve(const char *path, char *const argv[], char *const envp[],
selinux_execve(int fd, const char *path, char *const argv[], char *envp[],
bool noexec)
{
char **nargv;
@@ -409,6 +409,8 @@ selinux_execve(const char *path, char *const argv[], char *const envp[],
*/
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 @@ selinux_execve(const char *path, char *const argv[], char *const envp[],
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;

View File

@@ -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 @@ main(int argc, char *argv[], char *envp[])
} 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 @@ main(int argc, char *argv[], char *envp[])
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 @@ main(int argc, char *argv[], char *envp[])
*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;
}

View File

@@ -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 @@ command_info_to_details(char * const info[], struct command_details *details)
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 @@ command_info_to_details(char * const info[], struct command_details *details)
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)

View File

@@ -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 @@ struct command_details {
int ngroups;
int closefrom;
int flags;
int execfd;
struct preserved_fd_list preserved_fds;
struct passwd *pw;
GETGROUPS_T *groups;
@@ -221,8 +222,8 @@ int os_init_openbsd(int argc, char *argv[], char *envp[]);
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[],
bool noexec);
void selinux_execve(int fd, const char *path, char *const argv[],
char *envp[], bool noexec);
/* solaris.c */
void set_project(struct passwd *);

View File

@@ -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 *envp[], bool noexec);
int sudo_execve(int fd, const char *path, char *const argv[], char *envp[], bool noexec);
extern volatile pid_t cmnd_pid;
/* exec_pty.c */