Make the log_children option only log and not check policy.

This commit is contained in:
Todd C. Miller
2021-08-09 15:50:25 -06:00
parent 258fa9d4f9
commit 13b89e9103
3 changed files with 122 additions and 88 deletions

View File

@@ -480,7 +480,15 @@ terminate_command(pid_t pid, bool use_pgrp)
debug_return; debug_return;
} }
/* Must match start of exec_closure_nopty and monitor_closure. */
struct intercept_fd_closure {
struct command_details *details;
struct sudo_event_base *evbase;
};
/* Closure for intercept_cb() */
struct intercept_closure { struct intercept_closure {
struct command_details *details;
struct sudo_event ev; struct sudo_event ev;
const char *errstr; const char *errstr;
char *command; /* dynamically allocated */ char *command; /* dynamically allocated */
@@ -548,14 +556,14 @@ intercept_check_policy(PolicyCheckRequest *req,
{ {
char **command_info = NULL; char **command_info = NULL;
char **user_env_out = NULL; char **user_env_out = NULL;
char **argv, **run_argv = NULL; char **argv = NULL, **run_argv = NULL;
int ret = 1;
size_t n; size_t n;
int ok;
debug_decl(intercept_check_policy, SUDO_DEBUG_EXEC); debug_decl(intercept_check_policy, SUDO_DEBUG_EXEC);
if (req->command == NULL || req->n_argv == 0 || req->n_envp == 0) { if (req->command == NULL || req->n_argv == 0 || req->n_envp == 0) {
*errstr = N_("invalid PolicyCheckRequest"); *errstr = N_("invalid PolicyCheckRequest");
goto error; goto bad;
} }
if (sudo_debug_needed(SUDO_DEBUG_INFO)) { if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
@@ -571,104 +579,127 @@ intercept_check_policy(PolicyCheckRequest *req,
argv = reallocarray(NULL, req->n_argv + 1, sizeof(char *)); argv = reallocarray(NULL, req->n_argv + 1, sizeof(char *));
if (argv == NULL) { if (argv == NULL) {
*errstr = N_("unable to allocate memory"); *errstr = N_("unable to allocate memory");
goto error; goto bad;
} }
for (n = 0; n < req->n_argv; n++) { argv[0] = req->command;
for (n = 1; n < req->n_argv; n++) {
argv[n] = req->argv[n]; argv[n] = req->argv[n];
} }
argv[n] = NULL; argv[n] = NULL;
/* We don't currently have a good way to validate the environment. */ if (ISSET(closure->details->flags, CD_INTERCEPT)) {
/* TODO: make sure LD_PRELOAD is preserved in environment */ /* We don't currently have a good way to validate the environment. */
sudo_debug_set_active_instance(policy_plugin.debug_instance); sudo_debug_set_active_instance(policy_plugin.debug_instance);
ok = policy_plugin.u.policy->check_policy(n, argv, NULL, ret = policy_plugin.u.policy->check_policy(n, argv, NULL,
&command_info, &run_argv, &user_env_out, errstr); &command_info, &run_argv, &user_env_out, errstr);
sudo_debug_set_active_instance(sudo_debug_instance); sudo_debug_set_active_instance(sudo_debug_instance);
free(argv); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"check_policy returns %d", ret);
switch (ok) { switch (ret) {
case 1: case 1:
/* Extract command path from command_info[] */ /* Extract command path from command_info[] */
if (command_info != NULL) { if (command_info != NULL) {
for (n = 0; command_info[n] != NULL; n++) { for (n = 0; command_info[n] != NULL; n++) {
const char *cp = command_info[n]; const char *cp = command_info[n];
if (strncmp(cp, "command=", sizeof("command=") - 1) == 0) { if (strncmp(cp, "command=", sizeof("command=") - 1) == 0) {
closure->command = strdup(cp + sizeof("command=") - 1); closure->command = strdup(cp + sizeof("command=") - 1);
if (closure->command == NULL) { if (closure->command == NULL) {
*errstr = N_("unable to allocate memory"); *errstr = N_("unable to allocate memory");
goto error; goto bad;
}
break;
} }
break;
} }
} }
break;
case 0:
if (*errstr == NULL)
*errstr = N_("command rejected by policy");
audit_reject(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
command_info);
goto done;
default:
goto bad;
} }
} else {
if (sudo_debug_needed(SUDO_DEBUG_INFO)) { /* No actual policy check, just logging child processes. */
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"run_command: %s", closure->command); "not checking policy, audit only");
for (n = 0; run_argv[n] != NULL; n++) { closure->command = strdup(req->command);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, if (closure->command == NULL) {
"run_argv[%zu]: %s", n, run_argv[n]);
}
}
/* run_argv strings may be part of PolicyCheckReq, make a copy. */
for (n = 0; run_argv[n] != NULL; n++)
continue;
closure->run_argv = reallocarray(NULL, n + 1, sizeof(char *));
if (closure->run_argv == NULL) {
*errstr = N_("unable to allocate memory"); *errstr = N_("unable to allocate memory");
goto error; goto bad;
} }
command_info = (char **)closure->details->info;
run_argv = argv;
}
if (sudo_debug_needed(SUDO_DEBUG_INFO)) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"run_command: %s", closure->command);
for (n = 0; run_argv[n] != NULL; n++) { for (n = 0; run_argv[n] != NULL; n++) {
closure->run_argv[n] = strdup(run_argv[n]); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
if (closure->run_argv[n] == NULL) { "run_argv[%zu]: %s", n, run_argv[n]);
*errstr = N_("unable to allocate memory");
goto error;
}
} }
closure->run_argv[n] = NULL; }
/* envp strings are part of PolicyCheckReq, make a copy. */ /* run_argv strings may be part of PolicyCheckReq, make a copy. */
closure->run_envp = reallocarray(NULL, req->n_envp + 1, sizeof(char *)); for (n = 0; run_argv[n] != NULL; n++)
if (closure->run_envp == NULL) { continue;
closure->run_argv = reallocarray(NULL, n + 1, sizeof(char *));
if (closure->run_argv == NULL) {
*errstr = N_("unable to allocate memory");
goto bad;
}
for (n = 0; run_argv[n] != NULL; n++) {
closure->run_argv[n] = strdup(run_argv[n]);
if (closure->run_argv[n] == NULL) {
*errstr = N_("unable to allocate memory"); *errstr = N_("unable to allocate memory");
goto error; goto bad;
} }
for (n = 0; n < req->n_envp; n++) { }
closure->run_envp[n] = strdup(req->envp[n]); closure->run_argv[n] = NULL;
if (closure->run_envp[n] == NULL) {
*errstr = N_("unable to allocate memory");
goto error;
}
}
closure->run_envp[n] = NULL;
/* envp strings are part of PolicyCheckReq, make a copy. */
closure->run_envp = reallocarray(NULL, req->n_envp + 1, sizeof(char *));
if (closure->run_envp == NULL) {
*errstr = N_("unable to allocate memory");
goto bad;
}
for (n = 0; n < req->n_envp; n++) {
closure->run_envp[n] = strdup(req->envp[n]);
if (closure->run_envp[n] == NULL) {
*errstr = N_("unable to allocate memory");
goto bad;
}
}
closure->run_envp[n] = NULL;
if (ISSET(closure->details->flags, CD_INTERCEPT)) {
audit_accept(policy_plugin.name, SUDO_POLICY_PLUGIN, command_info, audit_accept(policy_plugin.name, SUDO_POLICY_PLUGIN, command_info,
closure->run_argv, closure->run_envp); closure->run_argv, closure->run_envp);
/* Call approval plugins and audit the result. */ /* Call approval plugins and audit the result. */
if (!approval_check(command_info, closure->run_argv, closure->run_envp)) if (!approval_check(command_info, closure->run_argv, closure->run_envp))
debug_return_int(0); debug_return_int(0);
/* Audit the event again for the sudo front-end. */
audit_accept("sudo", SUDO_FRONT_END, command_info, closure->run_argv,
closure->run_envp);
debug_return_int(1);
case 0:
if (*errstr == NULL)
*errstr = N_("command rejected by policy");
audit_reject(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
command_info);
debug_return_int(0);
default:
error:
if (*errstr == NULL)
*errstr = N_("policy plugin error");
audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
command_info);
debug_return_int(-1);
} }
/* Audit the event again for the sudo front-end. */
audit_accept("sudo", SUDO_FRONT_END, command_info, closure->run_argv,
closure->run_envp);
done:
free(argv);
debug_return_int(ret);
bad:
free(argv);
if (*errstr == NULL)
*errstr = N_("policy plugin error");
audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, *errstr,
command_info);
debug_return_int(ret);
} }
/* /*
@@ -945,7 +976,7 @@ void
intercept_fd_cb(int fd, int what, void *v) intercept_fd_cb(int fd, int what, void *v)
{ {
struct intercept_closure *closure = NULL; struct intercept_closure *closure = NULL;
struct sudo_event_base *base = v; struct intercept_fd_closure *fdc = v;
struct msghdr msg; struct msghdr msg;
union { union {
struct cmsghdr hdr; struct cmsghdr hdr;
@@ -962,6 +993,7 @@ intercept_fd_cb(int fd, int what, void *v)
sudo_warnx("%s", U_("unable to allocate memory")); sudo_warnx("%s", U_("unable to allocate memory"));
goto bad; goto bad;
} }
closure->details = fdc->details;
/* /*
* We send a single byte of data along with the fd; some systems * We send a single byte of data along with the fd; some systems
@@ -1006,7 +1038,7 @@ intercept_fd_cb(int fd, int what, void *v)
sudo_warn("%s", U_("unable to add event to queue")); sudo_warn("%s", U_("unable to add event to queue"));
goto bad; goto bad;
} }
if (sudo_ev_add(base, &closure->ev, NULL, false) == -1) { if (sudo_ev_add(fdc->evbase, &closure->ev, NULL, false) == -1) {
sudo_warn("%s", U_("unable to add event to queue")); sudo_warn("%s", U_("unable to add event to queue"));
goto bad; goto bad;
} }

View File

@@ -38,10 +38,8 @@
#include "sudo_plugin.h" #include "sudo_plugin.h"
#include "sudo_plugin_int.h" #include "sudo_plugin_int.h"
/* Note that details and evbase must come first. */
struct exec_closure_nopty { struct exec_closure_nopty {
pid_t cmnd_pid;
pid_t ppgrp;
struct command_status *cstat;
struct command_details *details; struct command_details *details;
struct sudo_event_base *evbase; struct sudo_event_base *evbase;
struct sudo_event *errpipe_event; struct sudo_event *errpipe_event;
@@ -58,6 +56,9 @@ struct exec_closure_nopty {
struct sudo_event *sigchld_event; struct sudo_event *sigchld_event;
struct sudo_event *sigcont_event; struct sudo_event *sigcont_event;
struct sudo_event *siginfo_event; struct sudo_event *siginfo_event;
struct command_status *cstat;
pid_t cmnd_pid;
pid_t ppgrp;
}; };
static void handle_sigchld_nopty(struct exec_closure_nopty *ec); static void handle_sigchld_nopty(struct exec_closure_nopty *ec);
@@ -220,7 +221,7 @@ fill_exec_closure_nopty(struct exec_closure_nopty *ec,
/* Event for sudo_intercept.so (optional). */ /* Event for sudo_intercept.so (optional). */
if (intercept_fd != -1) { if (intercept_fd != -1) {
ec->intercept_event = sudo_ev_alloc(intercept_fd, ec->intercept_event = sudo_ev_alloc(intercept_fd,
SUDO_EV_READ|SUDO_EV_PERSIST, intercept_fd_cb, ec->evbase); SUDO_EV_READ|SUDO_EV_PERSIST, intercept_fd_cb, ec);
if (ec->intercept_event == NULL) if (ec->intercept_event == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
if (sudo_ev_add(ec->evbase, ec->intercept_event, NULL, false) == -1) if (sudo_ev_add(ec->evbase, ec->intercept_event, NULL, false) == -1)

View File

@@ -55,13 +55,8 @@ struct monitor_message {
}; };
TAILQ_HEAD(monitor_message_list, monitor_message); TAILQ_HEAD(monitor_message_list, monitor_message);
/* Note that details and evbase must come first. */
struct exec_closure_pty { struct exec_closure_pty {
pid_t monitor_pid;
pid_t cmnd_pid;
pid_t ppgrp;
short rows;
short cols;
struct command_status *cstat;
struct command_details *details; struct command_details *details;
struct sudo_event_base *evbase; struct sudo_event_base *evbase;
struct sudo_event *backchannel_event; struct sudo_event *backchannel_event;
@@ -77,7 +72,13 @@ struct exec_closure_pty {
struct sudo_event *sigusr2_event; struct sudo_event *sigusr2_event;
struct sudo_event *sigchld_event; struct sudo_event *sigchld_event;
struct sudo_event *sigwinch_event; struct sudo_event *sigwinch_event;
struct command_status *cstat;
struct monitor_message_list monitor_messages; struct monitor_message_list monitor_messages;
pid_t monitor_pid;
pid_t cmnd_pid;
pid_t ppgrp;
short rows;
short cols;
}; };
/* /*