checksummed.
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"
+
+
for ac_func in getgrouplist
do :
ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
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"
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])
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*)
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
This setting has no effect unless I/O logging is
enabled or _\bu_\bs_\be_\b__\bp_\bt_\by is enabled.
+ execfd=number
+ If specified, s\bsu\bud\bdo\bo will use the fexecve(2) system call
+ to execute the command instead of execve(2). The
+ specified _\bn_\bu_\bm_\bb_\be_\br 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
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 _\be_\bx_\be_\bc_\bf_\bd entry was added to the command_info list.
+
S\bSE\bEE\bE A\bAL\bLS\bSO\bO
sudo.conf(4), sudoers(4), sudo(1m)
file distributed with s\bsu\bud\bdo\bo 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
.\" 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
.\" 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"
\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.
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@),
.\"
-.\" 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
.\" 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
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.
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@ ,
$ 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 s\bsu\bud\bdo\bo
- 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 s\bsu\bud\bdo\bo 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.
file distributed with s\bsu\bud\bdo\bo 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
.\" 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
.\" 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"
.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"
.\"
-.\" 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
.\" 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
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
/*
- * 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
/* 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)
/*
- * 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
# include <netdb.h>
#endif /* HAVE_NETGROUP_H */
#include <dirent.h>
+#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
};
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++) {
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;
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)) {
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);
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);
}
/*
- * 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
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);
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)
/*
- * 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
const char *cwd;
char *iolog_file;
GETGROUPS_T *gids;
+ int execfd;
int ngids;
int closefrom;
int lines;
#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)
/*
- * 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
}
#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;
/*
- * 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
* 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;
/*
- * 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
}
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;
*/
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"));
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;
/*
- * 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
} 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] == '-';
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--;
*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;
}
/*
- * 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
memset(details, 0, sizeof(*details));
details->closefrom = -1;
+ details->execfd = -1;
TAILQ_INIT(&details->preserved_fds);
#define SET_STRING(s, n) \
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)
/*
- * 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
int ngroups;
int closefrom;
int flags;
+ int execfd;
struct preserved_fd_list preserved_fds;
struct passwd *pw;
GETGROUPS_T *groups;
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 *);
/*
- * 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
/* 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 */