Message ID | 20231213161412.23022-1-cgzones@googlemail.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | [UTIL-LINUX] sulogin: relabel terminal according to SELinux policy | expand |
On Wed, Dec 13, 2023 at 11:14 AM Christian Göttsche <cgzones@googlemail.com> wrote: > > The common SELinux practice is to have a distinct label for terminals in > use by logged in users. This allows to differentiate access on the > associated terminal (e.g. user_tty_device_t) vs foreign ones (e.g. > tty_device_t or sysadm_tty_device_t). Therefore the application > performing the user login and setting up the associated terminal should > label that terminal according to the loaded SELinux policy. Commonly > this is done by pam_selinux(7). Since sulogin(8) does not use pam(7) > perform the necessary steps manually. > > Fixes: https://github.com/util-linux/util-linux/issues/1578 > > Signed-off-by: Christian Göttsche <cgzones@googlemail.com> The SELinux parts look ok to me. Reviewed-by: James Carter <jwcart2@gmail.com> > --- > Upstream pull-request: https://github.com/util-linux/util-linux/pull/2650 > --- > login-utils/sulogin-consoles.c | 4 + > login-utils/sulogin-consoles.h | 4 + > login-utils/sulogin.c | 156 +++++++++++++++++++++++++++++---- > 3 files changed, 146 insertions(+), 18 deletions(-) > > diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c > index 9ae525556..0dca949f4 100644 > --- a/login-utils/sulogin-consoles.c > +++ b/login-utils/sulogin-consoles.c > @@ -341,6 +341,10 @@ int append_console(struct list_head *consoles, const char * const name) > tail->id = last ? last->id + 1 : 0; > tail->pid = -1; > memset(&tail->tio, 0, sizeof(tail->tio)); > +#ifdef HAVE_LIBSELINUX > + tail->reset_tty_context = NULL; > + tail->user_tty_context = NULL; > +#endif > > return 0; > } > diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h > index 12032c997..608c4f84f 100644 > --- a/login-utils/sulogin-consoles.h > +++ b/login-utils/sulogin-consoles.h > @@ -44,6 +44,10 @@ struct console { > pid_t pid; > struct chardata cp; > struct termios tio; > +#ifdef HAVE_LIBSELINUX > + char *reset_tty_context; > + char *user_tty_context; > +#endif > }; > > extern int detect_consoles(const char *device, int fallback, > diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c > index 019f35092..2682c30fb 100644 > --- a/login-utils/sulogin.c > +++ b/login-utils/sulogin.c > @@ -99,6 +99,81 @@ static int locked_account_password(const char * const passwd) > return 0; > } > > +#ifdef HAVE_LIBSELINUX > +/* > + * Cached check whether SELinux is enabled. > + */ > +static int is_selinux_enabled_cached(void) > +{ > + static int cache = -1; > + > + if (cache == -1) > + cache = is_selinux_enabled(); > + > + return cache; > +} > + > +/* Computed SELinux login context. */ > +static char *login_context; > + > +/* > + * Compute SELinux login context. > + */ > +static void compute_login_context(void) > +{ > + char *seuser = NULL; > + char *level = NULL; > + > + if (is_selinux_enabled_cached() == 0) > + goto cleanup; > + > + if (getseuserbyname("root", &seuser, &level) == -1) { > + warnx(_("failed to compute seuser")); > + goto cleanup; > + } > + > + if (get_default_context_with_level(seuser, level, NULL, &login_context) == -1) { > + warnx(_("failed to compute default context")); > + goto cleanup; > + } > + > +cleanup: > + free(seuser); > + free(level); > +} > + > +/* > + * Compute SELinux terminal context. > + */ > +static void tcinit_selinux(struct console *con) > +{ > + security_class_t tclass; > + > + if (!login_context) > + return; > + > + if (fgetfilecon(con->fd, &con->reset_tty_context) == -1) { > + warn(_("failed to get context of terminal %s"), con->tty); > + return; > + } > + > + tclass = string_to_security_class("chr_file"); > + if (tclass == 0) { > + warnx(_("security class chr_file not available")); > + freecon(con->reset_tty_context); > + con->reset_tty_context = NULL; > + return; > + } > + > + if (security_compute_relabel(login_context, con->reset_tty_context, tclass, &con->user_tty_context) == -1) { > + warnx(_("failed to compute relabel context of terminal")); > + freecon(con->reset_tty_context); > + con->reset_tty_context = NULL; > + return; > + } > +} > +#endif > + > /* > * Fix the tty modes and set reasonable defaults. > */ > @@ -132,6 +207,10 @@ static void tcinit(struct console *con) > errno = 0; > #endif > > +#ifdef HAVE_LIBSELINUX > + tcinit_selinux(con); > +#endif > + > #ifdef TIOCGSERIAL > if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0) > con->flags |= CON_SERIAL; > @@ -785,7 +864,7 @@ out: > /* > * Password was OK, execute a shell. > */ > -static void sushell(struct passwd *pwd) > +static void sushell(struct passwd *pwd, struct console *con) > { > char shell[PATH_MAX]; > char home[PATH_MAX]; > @@ -842,22 +921,21 @@ static void sushell(struct passwd *pwd) > mask_signal(SIGHUP, SIG_DFL, NULL); > > #ifdef HAVE_LIBSELINUX > - if (is_selinux_enabled() > 0) { > - char *scon = NULL; > - char *seuser = NULL; > - char *level = NULL; > - > - if (getseuserbyname("root", &seuser, &level) == 0) { > - if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { > - if (setexeccon(scon) != 0) > - warnx(_("setexeccon failed")); > - freecon(scon); > - } > + if (is_selinux_enabled_cached() == 1) { > + if (con->user_tty_context) { > + if (fsetfilecon(con->fd, con->user_tty_context) == -1) > + warn(_("failed to set context to %s for terminal %s"), con->user_tty_context, con->tty); > + } > + > + if (login_context) { > + if (setexeccon(login_context) == -1) > + warn(_("failed to set exec context to %s"), login_context); > } > - free(seuser); > - free(level); > } > +#else > + (void)con; > #endif > + > execl(su_shell, shell, (char *)NULL); > warn(_("failed to execute %s"), su_shell); > > @@ -866,6 +944,30 @@ static void sushell(struct passwd *pwd) > warn(_("failed to execute %s"), "/bin/sh"); > } > > +#ifdef HAVE_LIBSELINUX > +static void tcreset_selinux(struct list_head *consoles) { > + struct list_head *ptr; > + struct console *con; > + > + if (is_selinux_enabled_cached() == 0) > + return; > + > + list_for_each(ptr, consoles) { > + con = list_entry(ptr, struct console, entry); > + > + if (con->fd < 0) > + continue; > + if (!con->reset_tty_context) > + continue; > + if (fsetfilecon(con->fd, con->reset_tty_context) == -1) > + warn(_("failed to reset context to %s for terminal %s"), con->reset_tty_context, con->tty); > + > + freecon(con->reset_tty_context); > + con->reset_tty_context = NULL; > + } > +} > +#endif > + > static void usage(void) > { > FILE *out = stdout; > @@ -1015,6 +1117,10 @@ int main(int argc, char **argv) > return EXIT_FAILURE; > } > > +#ifdef HAVE_LIBSELINUX > + compute_login_context(); > +#endif > + > /* > * Ask for the password on the consoles. > */ > @@ -1034,9 +1140,18 @@ int main(int argc, char **argv) > } > ptr = (&consoles)->next; > > - if (ptr->next == &consoles) { > - con = list_entry(ptr, struct console, entry); > - goto nofork; > +#ifdef HAVE_LIBSELINUX > + /* > + * Always fork with SELinux enabled, so the parent can restore the > + * terminal context afterwards. > + */ > + if (is_selinux_enabled_cached() == 0) > +#endif > + { > + if (ptr->next == &consoles) { > + con = list_entry(ptr, struct console, entry); > + goto nofork; > + } > } > > > @@ -1087,7 +1202,7 @@ int main(int argc, char **argv) > #endif > if (doshell) { > /* sushell() unmask signals */ > - sushell(pwd); > + sushell(pwd, con); > > mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); > mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); > @@ -1193,5 +1308,10 @@ int main(int argc, char **argv) > } while (1); > > mask_signal(SIGCHLD, SIG_DFL, NULL); > + > +#ifdef HAVE_LIBSELINUX > + tcreset_selinux(&consoles); > +#endif > + > return EXIT_SUCCESS; > } > -- > 2.43.0 > >
On Fri, 5 Jan 2024 at 20:15, James Carter <jwcart2@gmail.com> wrote: > > On Wed, Dec 13, 2023 at 11:14 AM Christian Göttsche > <cgzones@googlemail.com> wrote: > > > > The common SELinux practice is to have a distinct label for terminals in > > use by logged in users. This allows to differentiate access on the > > associated terminal (e.g. user_tty_device_t) vs foreign ones (e.g. > > tty_device_t or sysadm_tty_device_t). Therefore the application > > performing the user login and setting up the associated terminal should > > label that terminal according to the loaded SELinux policy. Commonly > > this is done by pam_selinux(7). Since sulogin(8) does not use pam(7) > > perform the necessary steps manually. > > > > Fixes: https://github.com/util-linux/util-linux/issues/1578 > > > > Signed-off-by: Christian Göttsche <cgzones@googlemail.com> > > The SELinux parts look ok to me. > Reviewed-by: James Carter <jwcart2@gmail.com> Thanks for the review Jim. Applied via https://github.com/util-linux/util-linux/commit/eb02db62685cca30e5afc61652c8b6e9cd0774e9 > > > --- > > Upstream pull-request: https://github.com/util-linux/util-linux/pull/2650 > > --- > > login-utils/sulogin-consoles.c | 4 + > > login-utils/sulogin-consoles.h | 4 + > > login-utils/sulogin.c | 156 +++++++++++++++++++++++++++++---- > > 3 files changed, 146 insertions(+), 18 deletions(-) > > > > diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c > > index 9ae525556..0dca949f4 100644 > > --- a/login-utils/sulogin-consoles.c > > +++ b/login-utils/sulogin-consoles.c > > @@ -341,6 +341,10 @@ int append_console(struct list_head *consoles, const char * const name) > > tail->id = last ? last->id + 1 : 0; > > tail->pid = -1; > > memset(&tail->tio, 0, sizeof(tail->tio)); > > +#ifdef HAVE_LIBSELINUX > > + tail->reset_tty_context = NULL; > > + tail->user_tty_context = NULL; > > +#endif > > > > return 0; > > } > > diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h > > index 12032c997..608c4f84f 100644 > > --- a/login-utils/sulogin-consoles.h > > +++ b/login-utils/sulogin-consoles.h > > @@ -44,6 +44,10 @@ struct console { > > pid_t pid; > > struct chardata cp; > > struct termios tio; > > +#ifdef HAVE_LIBSELINUX > > + char *reset_tty_context; > > + char *user_tty_context; > > +#endif > > }; > > > > extern int detect_consoles(const char *device, int fallback, > > diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c > > index 019f35092..2682c30fb 100644 > > --- a/login-utils/sulogin.c > > +++ b/login-utils/sulogin.c > > @@ -99,6 +99,81 @@ static int locked_account_password(const char * const passwd) > > return 0; > > } > > > > +#ifdef HAVE_LIBSELINUX > > +/* > > + * Cached check whether SELinux is enabled. > > + */ > > +static int is_selinux_enabled_cached(void) > > +{ > > + static int cache = -1; > > + > > + if (cache == -1) > > + cache = is_selinux_enabled(); > > + > > + return cache; > > +} > > + > > +/* Computed SELinux login context. */ > > +static char *login_context; > > + > > +/* > > + * Compute SELinux login context. > > + */ > > +static void compute_login_context(void) > > +{ > > + char *seuser = NULL; > > + char *level = NULL; > > + > > + if (is_selinux_enabled_cached() == 0) > > + goto cleanup; > > + > > + if (getseuserbyname("root", &seuser, &level) == -1) { > > + warnx(_("failed to compute seuser")); > > + goto cleanup; > > + } > > + > > + if (get_default_context_with_level(seuser, level, NULL, &login_context) == -1) { > > + warnx(_("failed to compute default context")); > > + goto cleanup; > > + } > > + > > +cleanup: > > + free(seuser); > > + free(level); > > +} > > + > > +/* > > + * Compute SELinux terminal context. > > + */ > > +static void tcinit_selinux(struct console *con) > > +{ > > + security_class_t tclass; > > + > > + if (!login_context) > > + return; > > + > > + if (fgetfilecon(con->fd, &con->reset_tty_context) == -1) { > > + warn(_("failed to get context of terminal %s"), con->tty); > > + return; > > + } > > + > > + tclass = string_to_security_class("chr_file"); > > + if (tclass == 0) { > > + warnx(_("security class chr_file not available")); > > + freecon(con->reset_tty_context); > > + con->reset_tty_context = NULL; > > + return; > > + } > > + > > + if (security_compute_relabel(login_context, con->reset_tty_context, tclass, &con->user_tty_context) == -1) { > > + warnx(_("failed to compute relabel context of terminal")); > > + freecon(con->reset_tty_context); > > + con->reset_tty_context = NULL; > > + return; > > + } > > +} > > +#endif > > + > > /* > > * Fix the tty modes and set reasonable defaults. > > */ > > @@ -132,6 +207,10 @@ static void tcinit(struct console *con) > > errno = 0; > > #endif > > > > +#ifdef HAVE_LIBSELINUX > > + tcinit_selinux(con); > > +#endif > > + > > #ifdef TIOCGSERIAL > > if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0) > > con->flags |= CON_SERIAL; > > @@ -785,7 +864,7 @@ out: > > /* > > * Password was OK, execute a shell. > > */ > > -static void sushell(struct passwd *pwd) > > +static void sushell(struct passwd *pwd, struct console *con) > > { > > char shell[PATH_MAX]; > > char home[PATH_MAX]; > > @@ -842,22 +921,21 @@ static void sushell(struct passwd *pwd) > > mask_signal(SIGHUP, SIG_DFL, NULL); > > > > #ifdef HAVE_LIBSELINUX > > - if (is_selinux_enabled() > 0) { > > - char *scon = NULL; > > - char *seuser = NULL; > > - char *level = NULL; > > - > > - if (getseuserbyname("root", &seuser, &level) == 0) { > > - if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { > > - if (setexeccon(scon) != 0) > > - warnx(_("setexeccon failed")); > > - freecon(scon); > > - } > > + if (is_selinux_enabled_cached() == 1) { > > + if (con->user_tty_context) { > > + if (fsetfilecon(con->fd, con->user_tty_context) == -1) > > + warn(_("failed to set context to %s for terminal %s"), con->user_tty_context, con->tty); > > + } > > + > > + if (login_context) { > > + if (setexeccon(login_context) == -1) > > + warn(_("failed to set exec context to %s"), login_context); > > } > > - free(seuser); > > - free(level); > > } > > +#else > > + (void)con; > > #endif > > + > > execl(su_shell, shell, (char *)NULL); > > warn(_("failed to execute %s"), su_shell); > > > > @@ -866,6 +944,30 @@ static void sushell(struct passwd *pwd) > > warn(_("failed to execute %s"), "/bin/sh"); > > } > > > > +#ifdef HAVE_LIBSELINUX > > +static void tcreset_selinux(struct list_head *consoles) { > > + struct list_head *ptr; > > + struct console *con; > > + > > + if (is_selinux_enabled_cached() == 0) > > + return; > > + > > + list_for_each(ptr, consoles) { > > + con = list_entry(ptr, struct console, entry); > > + > > + if (con->fd < 0) > > + continue; > > + if (!con->reset_tty_context) > > + continue; > > + if (fsetfilecon(con->fd, con->reset_tty_context) == -1) > > + warn(_("failed to reset context to %s for terminal %s"), con->reset_tty_context, con->tty); > > + > > + freecon(con->reset_tty_context); > > + con->reset_tty_context = NULL; > > + } > > +} > > +#endif > > + > > static void usage(void) > > { > > FILE *out = stdout; > > @@ -1015,6 +1117,10 @@ int main(int argc, char **argv) > > return EXIT_FAILURE; > > } > > > > +#ifdef HAVE_LIBSELINUX > > + compute_login_context(); > > +#endif > > + > > /* > > * Ask for the password on the consoles. > > */ > > @@ -1034,9 +1140,18 @@ int main(int argc, char **argv) > > } > > ptr = (&consoles)->next; > > > > - if (ptr->next == &consoles) { > > - con = list_entry(ptr, struct console, entry); > > - goto nofork; > > +#ifdef HAVE_LIBSELINUX > > + /* > > + * Always fork with SELinux enabled, so the parent can restore the > > + * terminal context afterwards. > > + */ > > + if (is_selinux_enabled_cached() == 0) > > +#endif > > + { > > + if (ptr->next == &consoles) { > > + con = list_entry(ptr, struct console, entry); > > + goto nofork; > > + } > > } > > > > > > @@ -1087,7 +1202,7 @@ int main(int argc, char **argv) > > #endif > > if (doshell) { > > /* sushell() unmask signals */ > > - sushell(pwd); > > + sushell(pwd, con); > > > > mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); > > mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); > > @@ -1193,5 +1308,10 @@ int main(int argc, char **argv) > > } while (1); > > > > mask_signal(SIGCHLD, SIG_DFL, NULL); > > + > > +#ifdef HAVE_LIBSELINUX > > + tcreset_selinux(&consoles); > > +#endif > > + > > return EXIT_SUCCESS; > > } > > -- > > 2.43.0 > > > >
diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c index 9ae525556..0dca949f4 100644 --- a/login-utils/sulogin-consoles.c +++ b/login-utils/sulogin-consoles.c @@ -341,6 +341,10 @@ int append_console(struct list_head *consoles, const char * const name) tail->id = last ? last->id + 1 : 0; tail->pid = -1; memset(&tail->tio, 0, sizeof(tail->tio)); +#ifdef HAVE_LIBSELINUX + tail->reset_tty_context = NULL; + tail->user_tty_context = NULL; +#endif return 0; } diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h index 12032c997..608c4f84f 100644 --- a/login-utils/sulogin-consoles.h +++ b/login-utils/sulogin-consoles.h @@ -44,6 +44,10 @@ struct console { pid_t pid; struct chardata cp; struct termios tio; +#ifdef HAVE_LIBSELINUX + char *reset_tty_context; + char *user_tty_context; +#endif }; extern int detect_consoles(const char *device, int fallback, diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c index 019f35092..2682c30fb 100644 --- a/login-utils/sulogin.c +++ b/login-utils/sulogin.c @@ -99,6 +99,81 @@ static int locked_account_password(const char * const passwd) return 0; } +#ifdef HAVE_LIBSELINUX +/* + * Cached check whether SELinux is enabled. + */ +static int is_selinux_enabled_cached(void) +{ + static int cache = -1; + + if (cache == -1) + cache = is_selinux_enabled(); + + return cache; +} + +/* Computed SELinux login context. */ +static char *login_context; + +/* + * Compute SELinux login context. + */ +static void compute_login_context(void) +{ + char *seuser = NULL; + char *level = NULL; + + if (is_selinux_enabled_cached() == 0) + goto cleanup; + + if (getseuserbyname("root", &seuser, &level) == -1) { + warnx(_("failed to compute seuser")); + goto cleanup; + } + + if (get_default_context_with_level(seuser, level, NULL, &login_context) == -1) { + warnx(_("failed to compute default context")); + goto cleanup; + } + +cleanup: + free(seuser); + free(level); +} + +/* + * Compute SELinux terminal context. + */ +static void tcinit_selinux(struct console *con) +{ + security_class_t tclass; + + if (!login_context) + return; + + if (fgetfilecon(con->fd, &con->reset_tty_context) == -1) { + warn(_("failed to get context of terminal %s"), con->tty); + return; + } + + tclass = string_to_security_class("chr_file"); + if (tclass == 0) { + warnx(_("security class chr_file not available")); + freecon(con->reset_tty_context); + con->reset_tty_context = NULL; + return; + } + + if (security_compute_relabel(login_context, con->reset_tty_context, tclass, &con->user_tty_context) == -1) { + warnx(_("failed to compute relabel context of terminal")); + freecon(con->reset_tty_context); + con->reset_tty_context = NULL; + return; + } +} +#endif + /* * Fix the tty modes and set reasonable defaults. */ @@ -132,6 +207,10 @@ static void tcinit(struct console *con) errno = 0; #endif +#ifdef HAVE_LIBSELINUX + tcinit_selinux(con); +#endif + #ifdef TIOCGSERIAL if (ioctl(fd, TIOCGSERIAL, &serinfo) >= 0) con->flags |= CON_SERIAL; @@ -785,7 +864,7 @@ out: /* * Password was OK, execute a shell. */ -static void sushell(struct passwd *pwd) +static void sushell(struct passwd *pwd, struct console *con) { char shell[PATH_MAX]; char home[PATH_MAX]; @@ -842,22 +921,21 @@ static void sushell(struct passwd *pwd) mask_signal(SIGHUP, SIG_DFL, NULL); #ifdef HAVE_LIBSELINUX - if (is_selinux_enabled() > 0) { - char *scon = NULL; - char *seuser = NULL; - char *level = NULL; - - if (getseuserbyname("root", &seuser, &level) == 0) { - if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { - if (setexeccon(scon) != 0) - warnx(_("setexeccon failed")); - freecon(scon); - } + if (is_selinux_enabled_cached() == 1) { + if (con->user_tty_context) { + if (fsetfilecon(con->fd, con->user_tty_context) == -1) + warn(_("failed to set context to %s for terminal %s"), con->user_tty_context, con->tty); + } + + if (login_context) { + if (setexeccon(login_context) == -1) + warn(_("failed to set exec context to %s"), login_context); } - free(seuser); - free(level); } +#else + (void)con; #endif + execl(su_shell, shell, (char *)NULL); warn(_("failed to execute %s"), su_shell); @@ -866,6 +944,30 @@ static void sushell(struct passwd *pwd) warn(_("failed to execute %s"), "/bin/sh"); } +#ifdef HAVE_LIBSELINUX +static void tcreset_selinux(struct list_head *consoles) { + struct list_head *ptr; + struct console *con; + + if (is_selinux_enabled_cached() == 0) + return; + + list_for_each(ptr, consoles) { + con = list_entry(ptr, struct console, entry); + + if (con->fd < 0) + continue; + if (!con->reset_tty_context) + continue; + if (fsetfilecon(con->fd, con->reset_tty_context) == -1) + warn(_("failed to reset context to %s for terminal %s"), con->reset_tty_context, con->tty); + + freecon(con->reset_tty_context); + con->reset_tty_context = NULL; + } +} +#endif + static void usage(void) { FILE *out = stdout; @@ -1015,6 +1117,10 @@ int main(int argc, char **argv) return EXIT_FAILURE; } +#ifdef HAVE_LIBSELINUX + compute_login_context(); +#endif + /* * Ask for the password on the consoles. */ @@ -1034,9 +1140,18 @@ int main(int argc, char **argv) } ptr = (&consoles)->next; - if (ptr->next == &consoles) { - con = list_entry(ptr, struct console, entry); - goto nofork; +#ifdef HAVE_LIBSELINUX + /* + * Always fork with SELinux enabled, so the parent can restore the + * terminal context afterwards. + */ + if (is_selinux_enabled_cached() == 0) +#endif + { + if (ptr->next == &consoles) { + con = list_entry(ptr, struct console, entry); + goto nofork; + } } @@ -1087,7 +1202,7 @@ int main(int argc, char **argv) #endif if (doshell) { /* sushell() unmask signals */ - sushell(pwd); + sushell(pwd, con); mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); @@ -1193,5 +1308,10 @@ int main(int argc, char **argv) } while (1); mask_signal(SIGCHLD, SIG_DFL, NULL); + +#ifdef HAVE_LIBSELINUX + tcreset_selinux(&consoles); +#endif + return EXIT_SUCCESS; }
The common SELinux practice is to have a distinct label for terminals in use by logged in users. This allows to differentiate access on the associated terminal (e.g. user_tty_device_t) vs foreign ones (e.g. tty_device_t or sysadm_tty_device_t). Therefore the application performing the user login and setting up the associated terminal should label that terminal according to the loaded SELinux policy. Commonly this is done by pam_selinux(7). Since sulogin(8) does not use pam(7) perform the necessary steps manually. Fixes: https://github.com/util-linux/util-linux/issues/1578 Signed-off-by: Christian Göttsche <cgzones@googlemail.com> --- Upstream pull-request: https://github.com/util-linux/util-linux/pull/2650 --- login-utils/sulogin-consoles.c | 4 + login-utils/sulogin-consoles.h | 4 + login-utils/sulogin.c | 156 +++++++++++++++++++++++++++++---- 3 files changed, 146 insertions(+), 18 deletions(-)