Add intercept_verify sudoers option to control execve(2) argument checking.
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.TH "SUDOERS" "@mansectform@" "May 31, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDOERS" "@mansectform@" "July 29, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@@ -3399,6 +3399,31 @@ by default.
|
|||||||
.sp
|
.sp
|
||||||
This setting is only supported by version 1.9.8 or higher.
|
This setting is only supported by version 1.9.8 or higher.
|
||||||
.TP 18n
|
.TP 18n
|
||||||
|
intercept_verify
|
||||||
|
If set,
|
||||||
|
\fBsudo\fR
|
||||||
|
will attempt to verify that a command run in intercept mode has
|
||||||
|
the expected path name and command line arguments.
|
||||||
|
The process is stopped after
|
||||||
|
execve(2)
|
||||||
|
has completed but before the new command has had a chance to run.
|
||||||
|
In the case of a path name or argument mismatch, the command will be sent a
|
||||||
|
\fRSIGKILL\fR
|
||||||
|
signal and terminated.
|
||||||
|
This flag has no effect unless the
|
||||||
|
\fIintercept\fR
|
||||||
|
flag is enabled or the
|
||||||
|
\fIINTERCEPT\fR
|
||||||
|
tag has been set for the command and the
|
||||||
|
\fIintercept_type\fR
|
||||||
|
option is set to
|
||||||
|
\fItrace\fR.
|
||||||
|
This flag is
|
||||||
|
\fIon\fR
|
||||||
|
by default.
|
||||||
|
.sp
|
||||||
|
This setting is only supported by version 1.9.12 or higher.
|
||||||
|
.TP 18n
|
||||||
netgroup_tuple
|
netgroup_tuple
|
||||||
If set, netgroup lookups will be performed using the full netgroup
|
If set, netgroup lookups will be performed using the full netgroup
|
||||||
tuple: host name, user name, and domain (if one is set).
|
tuple: host name, user name, and domain (if one is set).
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
.nr BA @BAMAN@
|
.nr BA @BAMAN@
|
||||||
.nr LC @LCMAN@
|
.nr LC @LCMAN@
|
||||||
.nr PS @PSMAN@
|
.nr PS @PSMAN@
|
||||||
.Dd May 31, 2022
|
.Dd July 29, 2022
|
||||||
.Dt SUDOERS @mansectform@
|
.Dt SUDOERS @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -3220,6 +3220,30 @@ This flag is
|
|||||||
by default.
|
by default.
|
||||||
.Pp
|
.Pp
|
||||||
This setting is only supported by version 1.9.8 or higher.
|
This setting is only supported by version 1.9.8 or higher.
|
||||||
|
.It intercept_verify
|
||||||
|
If set,
|
||||||
|
.Nm sudo
|
||||||
|
will attempt to verify that a command run in intercept mode has
|
||||||
|
the expected path name and command line arguments.
|
||||||
|
The process is stopped after
|
||||||
|
.Xr execve 2
|
||||||
|
has completed but before the new command has had a chance to run.
|
||||||
|
In the case of a path name or argument mismatch, the command will be sent a
|
||||||
|
.Dv SIGKILL
|
||||||
|
signal and terminated.
|
||||||
|
This flag has no effect unless the
|
||||||
|
.Em intercept
|
||||||
|
flag is enabled or the
|
||||||
|
.Em INTERCEPT
|
||||||
|
tag has been set for the command and the
|
||||||
|
.Em intercept_type
|
||||||
|
option is set to
|
||||||
|
.Em trace .
|
||||||
|
This flag is
|
||||||
|
.Em on
|
||||||
|
by default.
|
||||||
|
.Pp
|
||||||
|
This setting is only supported by version 1.9.12 or higher.
|
||||||
.It netgroup_tuple
|
.It netgroup_tuple
|
||||||
If set, netgroup lookups will be performed using the full netgroup
|
If set, netgroup lookups will be performed using the full netgroup
|
||||||
tuple: host name, user name, and domain (if one is set).
|
tuple: host name, user name, and domain (if one is set).
|
||||||
|
@@ -667,6 +667,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|||||||
"intercept_type", T_TUPLE,
|
"intercept_type", T_TUPLE,
|
||||||
N_("The mechanism used by the intercept and log_subcmds options: %s"),
|
N_("The mechanism used by the intercept and log_subcmds options: %s"),
|
||||||
def_data_intercept_type,
|
def_data_intercept_type,
|
||||||
|
}, {
|
||||||
|
"intercept_verify", T_FLAG,
|
||||||
|
N_("Whether to verify the command and arguments after execution"),
|
||||||
|
NULL,
|
||||||
}, {
|
}, {
|
||||||
"apparmor_profile", T_STR,
|
"apparmor_profile", T_STR,
|
||||||
N_("AppArmor profile to use in the new security context: %s"),
|
N_("AppArmor profile to use in the new security context: %s"),
|
||||||
|
@@ -308,7 +308,9 @@
|
|||||||
#define def_passprompt_regex (sudo_defs_table[I_PASSPROMPT_REGEX].sd_un.list)
|
#define def_passprompt_regex (sudo_defs_table[I_PASSPROMPT_REGEX].sd_un.list)
|
||||||
#define I_INTERCEPT_TYPE 153
|
#define I_INTERCEPT_TYPE 153
|
||||||
#define def_intercept_type (sudo_defs_table[I_INTERCEPT_TYPE].sd_un.tuple)
|
#define def_intercept_type (sudo_defs_table[I_INTERCEPT_TYPE].sd_un.tuple)
|
||||||
#define I_APPARMOR_PROFILE 154
|
#define I_INTERCEPT_VERIFY 154
|
||||||
|
#define def_intercept_verify (sudo_defs_table[I_INTERCEPT_VERIFY].sd_un.flag)
|
||||||
|
#define I_APPARMOR_PROFILE 155
|
||||||
#define def_apparmor_profile (sudo_defs_table[I_APPARMOR_PROFILE].sd_un.str)
|
#define def_apparmor_profile (sudo_defs_table[I_APPARMOR_PROFILE].sd_un.str)
|
||||||
|
|
||||||
enum def_tuple {
|
enum def_tuple {
|
||||||
|
@@ -479,6 +479,9 @@ intercept_type
|
|||||||
T_TUPLE
|
T_TUPLE
|
||||||
"The mechanism used by the intercept and log_subcmds options: %s"
|
"The mechanism used by the intercept and log_subcmds options: %s"
|
||||||
dso trace
|
dso trace
|
||||||
|
intercept_verify
|
||||||
|
T_FLAG
|
||||||
|
"Whether to verify the command and arguments after execution"
|
||||||
apparmor_profile
|
apparmor_profile
|
||||||
T_STR
|
T_STR
|
||||||
"AppArmor profile to use in the new security context: %s"
|
"AppArmor profile to use in the new security context: %s"
|
||||||
|
@@ -549,6 +549,7 @@ init_defaults(void)
|
|||||||
if ((def_rlimit_core = strdup("0,0")) == NULL)
|
if ((def_rlimit_core = strdup("0,0")) == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
def_intercept_type = dso;
|
def_intercept_type = dso;
|
||||||
|
def_intercept_verify = true;
|
||||||
def_netgroup_tuple = false;
|
def_netgroup_tuple = false;
|
||||||
def_sudoedit_checkdir = true;
|
def_sudoedit_checkdir = true;
|
||||||
def_iolog_mode = S_IRUSR|S_IWUSR;
|
def_iolog_mode = S_IRUSR|S_IWUSR;
|
||||||
|
@@ -636,7 +636,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Increase the length of command_info as needed, it is *not* checked. */
|
/* Increase the length of command_info as needed, it is *not* checked. */
|
||||||
command_info = calloc(71, sizeof(char *));
|
command_info = calloc(72, sizeof(char *));
|
||||||
if (command_info == NULL)
|
if (command_info == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
@@ -812,6 +812,10 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
|
|||||||
if ((command_info[info_len++] = strdup("use_ptrace=true")) == NULL)
|
if ((command_info[info_len++] = strdup("use_ptrace=true")) == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
if (def_intercept_verify) {
|
||||||
|
if ((command_info[info_len++] = strdup("intercept_verify=true")) == NULL)
|
||||||
|
goto oom;
|
||||||
|
}
|
||||||
if (def_noexec) {
|
if (def_noexec) {
|
||||||
if ((command_info[info_len++] = strdup("noexec=true")) == NULL)
|
if ((command_info[info_len++] = strdup("noexec=true")) == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
@@ -1532,10 +1532,12 @@ ptrace_intercept_execve(pid_t pid, struct intercept_closure *closure)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closure->state == POLICY_ACCEPT) {
|
if (closure->state == POLICY_ACCEPT) {
|
||||||
/* Verify execve(2) args post-exec. */
|
if (ISSET(closure->details->flags, CD_INTERCEPT_VERIFY)) {
|
||||||
if (!ptrace_verify_post_exec(pid, ®s, closure)) {
|
/* Verify execve(2) args post-exec. */
|
||||||
if (errno != ESRCH)
|
if (!ptrace_verify_post_exec(pid, ®s, closure)) {
|
||||||
kill(pid, SIGKILL);
|
if (errno != ESRCH)
|
||||||
|
kill(pid, SIGKILL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -734,6 +734,7 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
SET_FLAG("intercept=", CD_INTERCEPT)
|
SET_FLAG("intercept=", CD_INTERCEPT)
|
||||||
|
SET_FLAG("intercept_verify=", CD_INTERCEPT_VERIFY)
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
SET_STRING("login_class=", login_class)
|
SET_STRING("login_class=", login_class)
|
||||||
|
49
src/sudo.h
49
src/sudo.h
@@ -149,30 +149,31 @@ struct user_details {
|
|||||||
int ts_cols;
|
int ts_cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CD_SET_UID 0x000001
|
#define CD_SET_UID 0x00000001
|
||||||
#define CD_SET_EUID 0x000002
|
#define CD_SET_EUID 0x00000002
|
||||||
#define CD_SET_GID 0x000004
|
#define CD_SET_GID 0x00000004
|
||||||
#define CD_SET_EGID 0x000008
|
#define CD_SET_EGID 0x00000008
|
||||||
#define CD_PRESERVE_GROUPS 0x000010
|
#define CD_PRESERVE_GROUPS 0x00000010
|
||||||
#define CD_INTERCEPT 0x000020
|
#define CD_INTERCEPT 0x00000020
|
||||||
#define CD_NOEXEC 0x000040
|
#define CD_NOEXEC 0x00000040
|
||||||
#define CD_SET_PRIORITY 0x000080
|
#define CD_SET_PRIORITY 0x00000080
|
||||||
#define CD_SET_UMASK 0x000100
|
#define CD_SET_UMASK 0x00000100
|
||||||
#define CD_SET_TIMEOUT 0x000200
|
#define CD_SET_TIMEOUT 0x00000200
|
||||||
#define CD_SUDOEDIT 0x000400
|
#define CD_SUDOEDIT 0x00000400
|
||||||
#define CD_BACKGROUND 0x000800
|
#define CD_BACKGROUND 0x00000800
|
||||||
#define CD_RBAC_ENABLED 0x001000
|
#define CD_RBAC_ENABLED 0x00001000
|
||||||
#define CD_USE_PTY 0x002000
|
#define CD_USE_PTY 0x00002000
|
||||||
#define CD_SET_UTMP 0x004000
|
#define CD_SET_UTMP 0x00004000
|
||||||
#define CD_EXEC_BG 0x008000
|
#define CD_EXEC_BG 0x00008000
|
||||||
#define CD_SUDOEDIT_FOLLOW 0x010000
|
#define CD_SUDOEDIT_FOLLOW 0x00010000
|
||||||
#define CD_SUDOEDIT_CHECKDIR 0x020000
|
#define CD_SUDOEDIT_CHECKDIR 0x00020000
|
||||||
#define CD_SET_GROUPS 0x040000
|
#define CD_SET_GROUPS 0x00040000
|
||||||
#define CD_LOGIN_SHELL 0x080000
|
#define CD_LOGIN_SHELL 0x00080000
|
||||||
#define CD_OVERRIDE_UMASK 0x100000
|
#define CD_OVERRIDE_UMASK 0x00100000
|
||||||
#define CD_LOG_SUBCMDS 0x200000
|
#define CD_LOG_SUBCMDS 0x00200000
|
||||||
#define CD_USE_PTRACE 0x400000
|
#define CD_USE_PTRACE 0x00400000
|
||||||
#define CD_FEXECVE 0x800000
|
#define CD_FEXECVE 0x00800000
|
||||||
|
#define CD_INTERCEPT_VERIFY 0x01000000
|
||||||
|
|
||||||
struct preserved_fd {
|
struct preserved_fd {
|
||||||
TAILQ_ENTRY(preserved_fd) entries;
|
TAILQ_ENTRY(preserved_fd) entries;
|
||||||
|
Reference in New Issue
Block a user