Check audit plugins for a close function too before execing command directly.

We cannot exec the command directly if any of the policy or audit
plugins use a close function.
This commit is contained in:
Todd C. Miller
2020-05-26 11:36:17 -06:00
parent d9cbb7bebd
commit 2dd1e1907d

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2009-2020 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -333,6 +333,30 @@ sudo_needs_pty(struct command_details *details)
return false; return false;
} }
/*
* If we are not running the command in a pty, we were not invoked as
* sudoedit, there is no command timeout and there is no close function,
* sudo can exec the command directly (and not wait).
*/
static bool
direct_exec_allowed(struct command_details *details)
{
struct plugin_container *plugin;
debug_decl(direct_exec_allowed, SUDO_DEBUG_EXEC);
/* Assumes sudo_needs_pty() was already checked. */
if (ISSET(details->flags, CD_SET_TIMEOUT|CD_SUDOEDIT) ||
policy_plugin.u.policy->close != NULL)
debug_return_bool(false);
TAILQ_FOREACH(plugin, &audit_plugins, entries) {
if (plugin->u.audit->close != NULL)
debug_return_bool(false);
}
debug_return_bool(true);
}
/* /*
* Execute a command, potentially in a pty with I/O logging, and * Execute a command, potentially in a pty with I/O logging, and
* wait for it to finish. * wait for it to finish.
@@ -380,12 +404,10 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
} }
/* /*
* If we are not running the command in a pty, we were not invoked * If we are not running the command in a pty, we may be able to
* as sudoedit, there is no command timeout and there is no close * exec directly, depending on the plugins used.
* function, just exec directly. Only returns on error.
*/ */
if (!ISSET(details->flags, CD_SET_TIMEOUT|CD_SUDOEDIT) && if (direct_exec_allowed(details)) {
policy_plugin.u.policy->close == NULL) {
if (!sudo_terminated(cstat)) { if (!sudo_terminated(cstat)) {
exec_cmnd(details, -1); exec_cmnd(details, -1);
cstat->type = CMD_ERRNO; cstat->type = CMD_ERRNO;