Add intercept_type sudoers option to set intercept/log_subcmds mechanism.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
14
src/sudo.c
14
src/sudo.c
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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__ */
|
||||
|
||||
|
Reference in New Issue
Block a user