Add intercept_type sudoers option to set intercept/log_subcmds mechanism.

This commit is contained in:
Todd C. Miller
2022-05-24 13:39:28 -06:00
parent b203753013
commit f053f174bc
13 changed files with 243 additions and 37 deletions

View File

@@ -51,6 +51,8 @@
# include "exec_intercept.h"
# include "exec_ptrace.h"
static int seccomp_trap_supported = -1;
/* Register getters and setters. */
# ifdef SECCOMP_AUDIT_ARCH_COMPAT
static inline unsigned long
@@ -736,7 +738,7 @@ done:
* Check whether seccomp(2) filtering supports ptrace(2) traps.
* Only supported by Linux 4.14 and higher.
*/
bool
static bool
have_seccomp_action(const char *action)
{
char line[LINE_MAX];
@@ -1274,6 +1276,24 @@ exec_ptrace_stopped(pid_t pid, int status, void *intercept)
debug_return_bool(group_stop);
}
bool
exec_ptrace_intercept_supported(void)
{
if (seccomp_trap_supported == -1)
seccomp_trap_supporetd = have_seccomp_action("trap");
return seccomp_trap_supported == true;
}
bool
exec_ptrace_subcmds_supported(void)
{
if (seccomp_trap_supported == -1)
seccomp_trap_supported = have_seccomp_action("trap");
return seccomp_trap_supported == true;
}
#else
/* STUB */
bool
@@ -1295,4 +1315,41 @@ exec_ptrace_seize(pid_t child)
{
return true;
}
/* STUB */
bool
exec_ptrace_intercept_supported(void)
{
return false;
}
/* STUB */
bool
exec_ptrace_subcmds_supported(void)
{
return false;
}
#endif /* HAVE_PTRACE_INTERCEPT */
/*
* Adjust flags based on the availability of ptrace support.
*/
void
exec_ptrace_fix_flags(struct command_details *details)
{
debug_decl(exec_ptrace_fix_flags, SUDO_DEBUG_EXEC);
if (ISSET(details->flags, CD_USE_PTRACE)) {
/* If both CD_INTERCEPT and CD_LOG_SUBCMDS set, CD_INTERCEPT wins. */
if (ISSET(details->flags, CD_INTERCEPT)) {
if (!exec_ptrace_intercept_supported())
CLR(details->flags, CD_USE_PTRACE);
} else if (ISSET(details->flags, CD_LOG_SUBCMDS)) {
if (!exec_ptrace_subcmds_supported())
CLR(details->flags, CD_USE_PTRACE);
} else {
CLR(details->flags, CD_USE_PTRACE);
}
}
debug_return;
}

View File

@@ -82,6 +82,7 @@ static struct sudo_settings sudo_settings[] = {
{ "cmnd_cwd" },
{ "askpass" },
{ "intercept_setid" },
{ "intercept_ptrace" },
{ NULL }
};
@@ -585,8 +586,10 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv,
#ifdef ENABLE_SUDO_PLUGIN_API
sudo_settings[ARG_PLUGIN_DIR].value = sudo_conf_plugin_dir_path();
#endif
if (have_seccomp_action("trap"))
if (exec_ptrace_intercept_supported())
sudo_settings[ARG_INTERCEPT_SETID].value = "true";
if (exec_ptrace_subcmds_supported())
sudo_settings[ARG_INTERCEPT_PTRACE].value = "true";
if (mode == MODE_HELP)
help();

View File

@@ -650,10 +650,10 @@ bad:
static void
command_info_to_details(char * const info[], struct command_details *details)
{
int i;
id_t id;
char *cp;
const char *errstr;
char *cp;
id_t id;
int i;
debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM);
memset(details, 0, sizeof(*details));
@@ -857,17 +857,15 @@ command_info_to_details(char * const info[], struct command_details *details)
break;
}
SET_FLAG("umask_override=", CD_OVERRIDE_UMASK)
SET_FLAG("use_ptrace=", CD_USE_PTRACE)
SET_FLAG("use_pty=", CD_USE_PTY)
SET_STRING("utmp_user=", utmp_user)
break;
}
}
if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) {
/* Use ptrace(2) for intercept/log_subcmds if possible. */
if (sudo_settings[ARG_INTERCEPT_SETID].value != NULL)
SET(details->flags, CD_USE_PTRACE);
}
/* Only use ptrace(2) for intercept/log_subcmds if supported. */
exec_ptrace_fix_flags(details);
if (!ISSET(details->flags, CD_SET_EUID))
details->cred.euid = details->cred.uid;

View File

@@ -103,6 +103,7 @@
#define ARG_CWD 24
#define ARG_ASKPASS 25
#define ARG_INTERCEPT_SETID 26
#define ARG_INTERCEPT_PTRACE 27
/*
* Flags for tgetpass()
@@ -338,6 +339,8 @@ int serialize_rlimits(char **info, size_t info_max);
bool parse_policy_rlimit(const char *str);
/* exec_ptrace.c */
bool have_seccomp_action(const char *action);
void exec_ptrace_fix_flags(struct command_details *details);
bool exec_ptrace_intercept_supported(void);
bool exec_ptrace_subcmds_supported(void);
#endif /* SUDO_SUDO_H */

View File

@@ -92,7 +92,6 @@ union sudo_token_un {
/*
* Use ptrace-based intercept (using seccomp) on Linux if possible.
* TODO: test other architectures
*/
#if defined(_PATH_SUDO_INTERCEPT) && defined(__linux__)
# if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
@@ -100,7 +99,7 @@ union sudo_token_un {
# ifndef HAVE_PTRACE_INTERCEPT
# define HAVE_PTRACE_INTERCEPT 1
# endif /* HAVE_PTRACE_INTERCEPT */
# endif /* __amd64__ || __i386__ || __aarch64__ || __riscv */
# endif /* __amd64__ || __i386__ || __aarch64__ || __riscv || __s390__ */
# endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */
#endif /* _PATH_SUDO_INTERCEPT && __linux__ */