debug_return_bool(stat(path, sb) == 0);
}
-#ifdef HAVE_FEXECVE
/*
* Check whether the fd refers to a shell script with a "#!" shebang.
*/
if (fd == -1)
debug_return_bool(false);
- if (is_script(fd)) {
- char fdpath[PATH_MAX];
- struct stat sb;
+ (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
+ *fdp = fd;
+ debug_return_bool(true);
+}
+
+static void
+set_cmnd_fd(int fd)
+{
+ debug_decl(set_cmnd_fd, SUDOERS_DEBUG_MATCH)
+
+ if (cmnd_fd != -1)
+ close(cmnd_fd);
- /* We can only use fexecve() on a script if /dev/fd/N exists. */
- snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd);
- if (stat(fdpath, &sb) != 0) {
+ if (fd != -1) {
+ if (def_fdexec == never) {
+ /* Never use fexedcve() */
close(fd);
- debug_return_bool(true);
+ fd = -1;
+ } else if (is_script(fd)) {
+ char fdpath[PATH_MAX];
+ struct stat sb;
+ int flags;
+
+ /* We can only use fexecve() on a script if /dev/fd/N exists. */
+ snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd);
+ if (stat(fdpath, &sb) != 0) {
+ /* Missing /dev/fd file, can't use fexecve(). */
+ close(fd);
+ fd = -1;
+ } else {
+ /*
+ * Shell scripts go through namei twice so we can't have the
+ * close on exec flag set on the fd for fexecve(2).
+ */
+ flags = fcntl(fd, F_GETFD) & ~FD_CLOEXEC;
+ (void)fcntl(fd, F_SETFD, flags);
+ }
}
-
- /*
- * Shell scripts go through namei twice so we can't set the
- * close on exec flag on the fd for fexecve(2).
- */
- } else {
- /* Not a script, close on exec is safe. */
- (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
}
- *fdp = fd;
- debug_return_bool(true);
-}
-#else /* HAVE_FEXECVE */
-static bool
-open_cmnd(const char *path, const struct sudo_digest *digest, int *fdp)
-{
- return true;
+ cmnd_fd = fd;
+
+ debug_return;
}
-#endif /* HAVE_FEXECVE */
static bool
command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
const struct sudo_digest *digest)
{
struct stat sb; /* XXX - unused */
+ int fd = -1;
debug_decl(command_matches_fnmatch, SUDOERS_DEBUG_MATCH)
/*
if (fnmatch(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0)
debug_return_bool(false);
if (command_args_match(sudoers_cmnd, sudoers_args)) {
- if (cmnd_fd != -1) {
- close(cmnd_fd);
- cmnd_fd = -1;
- }
/* Open the file for fdexec or for digest matching. */
- if (!open_cmnd(user_cmnd, digest, &cmnd_fd))
+ if (!open_cmnd(user_cmnd, digest, &fd))
goto bad;
- if (!do_stat(cmnd_fd, user_cmnd, &sb))
+ if (!do_stat(fd, user_cmnd, &sb))
goto bad;
/* Check digest of user_cmnd since sudoers_cmnd is a pattern. */
- if (digest != NULL) {
- if (!digest_matches(cmnd_fd, user_cmnd, digest))
- goto bad;
- if (def_fdexec == never) {
- close(cmnd_fd);
- cmnd_fd = -1;
- }
- }
+ if (digest != NULL && !digest_matches(fd, user_cmnd, digest))
+ goto bad;
+ set_cmnd_fd(fd);
+
/* No need to set safe_cmnd since user_cmnd matches sudoers_cmnd */
debug_return_bool(true);
bad:
- if (cmnd_fd != -1) {
- close(cmnd_fd);
- cmnd_fd = -1;
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
}
debug_return_bool(false);
}
if (cp != NULL) {
if (command_args_match(sudoers_cmnd, sudoers_args)) {
/* safe_cmnd was set above. */
- if (cmnd_fd != -1) {
- close(cmnd_fd);
- cmnd_fd = -1;
- }
- if (fd != -1) {
- if (def_fdexec == never)
- close(fd);
- else
- cmnd_fd = fd;
- }
+ set_cmnd_fd(fd);
debug_return_bool(true);
}
}
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto bad;
}
- if (cmnd_fd != -1) {
- close(cmnd_fd);
- cmnd_fd = -1;
- }
- if (fd != -1) {
- if (def_fdexec == never)
- close(fd);
- else
- cmnd_fd = fd;
- }
+ set_cmnd_fd(fd);
debug_return_bool(true);
bad:
if (fd != -1)
closedir(dirp);
if (dent != NULL) {
- if (cmnd_fd != -1) {
- close(cmnd_fd);
- cmnd_fd = -1;
- }
- if (fd != -1) {
- if (def_fdexec == never)
- close(fd);
- else
- cmnd_fd = fd;
- }
+ set_cmnd_fd(fd);
debug_return_bool(true);
}
if (fd != -1)