Pass status of selinux sudoers setting to front-end as selinux-rbac.

The front-end uses this to decide whether or not to enable SELinux.
If selinux-rbac is true _or_ if it is not present and selinux_role or
selinux_type are set, SELinux support is enabled.
Previously, SELinux support was only enabled if a role was specified.
This commit is contained in:
Todd C. Miller
2021-11-05 12:32:02 -06:00
parent 6804632591
commit a336a8422f
3 changed files with 40 additions and 24 deletions

View File

@@ -632,7 +632,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(57, sizeof(char *)); command_info = calloc(58, sizeof(char *));
if (command_info == NULL) if (command_info == NULL)
goto oom; goto oom;
@@ -897,6 +897,9 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[],
} }
#endif /* HAVE_LOGIN_CAP_H */ #endif /* HAVE_LOGIN_CAP_H */
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (asprintf(&command_info[info_len++], "selinux_rbac=%s",
def_selinux ? "true" : "false") == -1)
goto oom;
if (def_selinux && user_role != NULL) { if (def_selinux && user_role != NULL) {
if ((command_info[info_len++] = sudo_new_key_val("selinux_role", user_role)) == NULL) if ((command_info[info_len++] = sudo_new_key_val("selinux_role", user_role)) == NULL)
goto oom; goto oom;

View File

@@ -309,19 +309,29 @@ bad:
* specified role and type. * specified role and type.
*/ */
static char * static char *
get_exec_context(char * old_context, const char *role, const char *type) get_exec_context(char *old_context, const char *role, const char *type)
{ {
char * new_context = NULL; char *rolebuf = NULL, *typebuf = NULL;
char *new_context = NULL;
context_t context = NULL; context_t context = NULL;
char *typebuf = NULL;
debug_decl(get_exec_context, SUDO_DEBUG_SELINUX); debug_decl(get_exec_context, SUDO_DEBUG_SELINUX);
/* We must have a role, the type is optional (we can use the default). */ /*
if (role == NULL) { * Expand old_context into a context_t so that we can extract and modify
sudo_warnx(U_("you must specify a role for type %s"), type); * its components easily.
errno = EINVAL; */
if ((context = context_new(old_context)) == NULL) {
sudo_warn("%s", U_("failed to get new context"));
goto bad; goto bad;
} }
if (role == NULL) {
/* TODO: if role is unconfined_r and type is NULL, disable SELinux */
rolebuf = strdup(context_role_get(context));
if (rolebuf == NULL)
goto bad;
role = rolebuf;
}
if (type == NULL) { if (type == NULL) {
if (get_default_type(role, &typebuf)) { if (get_default_type(role, &typebuf)) {
sudo_warnx(U_("unable to get default type for role %s"), role); sudo_warnx(U_("unable to get default type for role %s"), role);
@@ -330,16 +340,7 @@ get_exec_context(char * old_context, const char *role, const char *type)
} }
type = typebuf; type = typebuf;
} }
/*
* Expand old_context into a context_t so that we can extract and modify
* its components easily.
*/
if ((context = context_new(old_context)) == NULL) {
sudo_warn("%s", U_("failed to get new context"));
goto bad;
}
/* /*
* Replace the role and type in "context" with the role and * Replace the role and type in "context" with the role and
* type we will be running the command as. * type we will be running the command as.
@@ -352,7 +353,7 @@ get_exec_context(char * old_context, const char *role, const char *type)
sudo_warn(U_("failed to set new type %s"), type); sudo_warn(U_("failed to set new type %s"), type);
goto bad; goto bad;
} }
/* /*
* Convert "context" back into a string and verify it. * Convert "context" back into a string and verify it.
*/ */
@@ -370,13 +371,14 @@ get_exec_context(char * old_context, const char *role, const char *type)
debug_return_str(new_context); debug_return_str(new_context);
bad: bad:
free(rolebuf);
free(typebuf); free(typebuf);
context_free(context); context_free(context);
freecon(new_context); freecon(new_context);
debug_return_str(NULL); debug_return_str(NULL);
} }
/* /*
* Determine the exec and tty contexts in preparation for fork/exec. * Determine the exec and tty contexts in preparation for fork/exec.
* Must run as root, before forking the child process. * Must run as root, before forking the child process.
* Sets the tty context but not the exec context (which happens later). * Sets the tty context but not the exec context (which happens later).
@@ -414,7 +416,7 @@ selinux_setup(const char *role, const char *type, const char *ttyn,
} }
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: new context %s", __func__, sudo_debug_printf(SUDO_DEBUG_INFO, "%s: new context %s", __func__,
se_state.new_context); se_state.new_context);
if (label_tty && relabel_tty(ttyn, ptyfd) == -1) { if (label_tty && relabel_tty(ttyn, ptyfd) == -1) {
sudo_warn(U_("unable to set tty context to %s"), se_state.new_context); sudo_warn(U_("unable to set tty context to %s"), se_state.new_context);
goto done; goto done;

View File

@@ -647,7 +647,7 @@ bad:
static void static void
command_info_to_details(char * const info[], struct command_details *details) command_info_to_details(char * const info[], struct command_details *details)
{ {
int i; int i, selinux_rbac = -1;
id_t id; id_t id;
char *cp; char *cp;
const char *errstr; const char *errstr;
@@ -822,6 +822,14 @@ command_info_to_details(char * const info[], struct command_details *details)
SET_STRING("runas_user=", runas_user) SET_STRING("runas_user=", runas_user)
break; break;
case 's': case 's':
if (strncmp("selinux_rbac=", info[i], sizeof("selinux_rbac=") - 1) == 0) {
selinux_rbac = sudo_strtobool(info[i] + sizeof("selinux_rbac=") - 1);
if (selinux_rbac == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR,
"invalid boolean value for %s", info[i]);
}
break;
}
SET_STRING("selinux_role=", selinux_role) SET_STRING("selinux_role=", selinux_role)
SET_STRING("selinux_type=", selinux_type) SET_STRING("selinux_type=", selinux_type)
SET_FLAG("set_utmp=", CD_SET_UTMP) SET_FLAG("set_utmp=", CD_SET_UTMP)
@@ -876,7 +884,10 @@ command_info_to_details(char * const info[], struct command_details *details)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (details->selinux_role != NULL && is_selinux_enabled() > 0) /* Newer sudoers plugin sets selinux_rbac, older only sets role/type. */
if (selinux_rbac == -1)
selinux_rbac = details->selinux_role || details->selinux_type;
if (selinux_rbac && is_selinux_enabled() > 0)
SET(details->flags, CD_RBAC_ENABLED); SET(details->flags, CD_RBAC_ENABLED);
#endif #endif
debug_return; debug_return;