diff -up ./src/exec.c.tty2 ./src/exec.c
--- ./src/exec.c.tty2 2018-04-29 21:59:24.000000000 +0200
+++ ./src/exec.c 2021-07-02 13:34:53.803816249 +0200
@@ -99,19 +99,11 @@ restore_nproc(void)
* Returns true on success and false on failure.
*/
static bool
-exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
+exec_setup(struct command_details *details)
{
bool ret = false;
debug_decl(exec_setup, SUDO_DEBUG_EXEC)
-#ifdef HAVE_SELINUX
- if (ISSET(details->flags, CD_RBAC_ENABLED)) {
- if (selinux_setup(details->selinux_role, details->selinux_type,
- ptyname ? ptyname : user_details.tty, ptyfd) == -1)
- goto done;
- }
-#endif
-
/* Restore coredumpsize resource limit before running. */
if (sudo_conf_disable_coredump())
disable_coredump(true);
@@ -141,7 +133,7 @@ exec_setup(struct command_details *detai
#endif /* HAVE_PRIV_SET */
#ifdef HAVE_GETUSERATTR
- if (aix_prep_user(details->pw->pw_name, ptyname ? ptyname : user_details.tty) != 0) {
+ if (aix_prep_user(details->pw->pw_name, details->tty) != 0) {
/* error message displayed by aix_prep_user */
goto done;
}
@@ -262,7 +254,7 @@ exec_cmnd(struct command_details *detail
debug_decl(exec_cmnd, SUDO_DEBUG_EXEC)
restore_signals();
- if (exec_setup(details, NULL, -1) == true) {
+ if (exec_setup(details) == true) {
/* headed for execve() */
if (details->closefrom >= 0) {
int fd, maxfd;
diff -up ./src/exec_monitor.c.tty2 ./src/exec_monitor.c
--- ./src/exec_monitor.c.tty2 2021-07-02 10:07:33.951025634 +0200
+++ ./src/exec_monitor.c 2021-07-02 13:34:00.388475413 +0200
@@ -549,10 +549,26 @@ exec_monitor(struct command_details *det
if (pipe2(errpipe, O_CLOEXEC) != 0)
sudo_fatal(U_("unable to create pipe"));
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_setup(details->selinux_role, details->selinux_type,
+ details->tty, io_fds[SFD_SLAVE]) == -1)
+ goto bad;
+ }
+#endif
+
mc.cmnd_pid = sudo_debug_fork();
switch (mc.cmnd_pid) {
case -1:
sudo_warn(U_("unable to fork"));
+
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_restore_tty() != 0)
+ sudo_warnx(U_("unable to restore tty label"));
+ }
+#endif
+
goto bad;
case 0:
/* child */
diff -up ./src/exec_nopty.c.tty2 ./src/exec_nopty.c
--- ./src/exec_nopty.c.tty2 2018-04-29 21:59:31.000000000 +0200
+++ ./src/exec_nopty.c 2021-07-02 10:07:33.951025634 +0200
@@ -371,6 +371,17 @@ exec_nopty(struct command_details *detai
debug_return;
}
+#ifdef HAVE_SELINUX
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
+ if (selinux_setup(details->selinux_role, details->selinux_type,
+ details->tty, -1) == -1) {
+ cstat->type = CMD_ERRNO;
+ cstat->val = errno;
+ debug_return;
+ }
+ }
+#endif
+
ec.cmnd_pid = sudo_debug_fork();
switch (ec.cmnd_pid) {
case -1:
diff -up ./src/exec_pty.c.tty2 ./src/exec_pty.c
--- ./src/exec_pty.c.tty2 2021-07-02 10:07:33.940025770 +0200
+++ ./src/exec_pty.c 2021-07-02 13:40:49.569392687 +0200
@@ -95,7 +95,7 @@ struct io_buffer {
};
SLIST_HEAD(io_buffer_list, io_buffer);
-static char slavename[PATH_MAX];
+static char ptyname[PATH_MAX];
int io_fds[6] = { -1, -1, -1, -1, -1, -1};
static bool foreground, pipeline;
static bool tty_initialized;
@@ -123,7 +123,7 @@ pty_cleanup(void)
if (io_fds[SFD_USERTTY] != -1)
sudo_term_restore(io_fds[SFD_USERTTY], false);
if (utmp_user != NULL)
- utmp_logout(slavename, 0);
+ utmp_logout(ptyname, 0);
debug_return;
}
@@ -131,7 +131,7 @@ pty_cleanup(void)
/*
* Allocate a pty if /dev/tty is a tty.
* Fills in io_fds[SFD_USERTTY], io_fds[SFD_MASTER], io_fds[SFD_SLAVE]
- * and slavename globals.
+ * and ptyname globals.
*/
static bool
pty_setup(struct command_details *details, const char *tty)
@@ -146,14 +146,17 @@ pty_setup(struct command_details *detail
}
if (!get_pty(&io_fds[SFD_MASTER], &io_fds[SFD_SLAVE],
- slavename, sizeof(slavename), details->euid))
+ ptyname, sizeof(ptyname), details->euid))
sudo_fatal(U_("unable to allocate pty"));
+ /* Update tty name in command details (used by SELinux and AIX). */
+ details->tty = ptyname;
+
/* Add entry to utmp/utmpx? */
if (ISSET(details->flags, CD_SET_UTMP)) {
utmp_user =
details->utmp_user ? details->utmp_user : user_details.username;
- utmp_login(tty, slavename, io_fds[SFD_SLAVE], utmp_user);
+ utmp_login(tty, ptyname, io_fds[SFD_SLAVE], utmp_user);
}
sudo_debug_printf(SUDO_DEBUG_INFO,
@@ -172,8 +175,8 @@ pty_make_controlling(void)
if (ioctl(io_fds[SFD_SLAVE], TIOCSCTTY, NULL) != 0)
return -1;
#else
- /* Set controlling tty by reopening slave. */
- int fd = open(slavename, O_RDWR);
+ /* Set controlling tty by reopening pty slave. */
+ int fd = open(ptyname, O_RDWR);
if (fd == -1)
return -1;
close(fd);
@@ -787,7 +790,7 @@ pty_close(struct command_status *cstat)
/* Update utmp */
if (utmp_user != NULL)
- utmp_logout(slavename, cstat->type == CMD_WSTATUS ? cstat->val : 0);
+ utmp_logout(ptyname, cstat->type == CMD_WSTATUS ? cstat->val : 0);
/* Close pty master. */
if (io_fds[SFD_MASTER] != -1)
diff -up ./src/selinux.c.tty2 ./src/selinux.c
--- ./src/selinux.c.tty2 2021-07-02 10:07:33.950025646 +0200
+++ ./src/selinux.c 2021-07-02 10:07:33.952025622 +0200
@@ -123,10 +123,11 @@ selinux_restore_tty(void)
goto skip_relabel;
}
- if (strcmp(chk_tty_context, se_state.new_tty_context) == 0) {
+ if (strcmp(chk_tty_context, se_state.new_tty_context) != 0) {
sudo_warnx(U_("%s changed labels"), se_state.ttyn);
- sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tty label changed, skipping",
- __func__);
+ sudo_debug_printf(SUDO_DEBUG_INFO,
+ "%s: not restoring tty label, expected %s, have %s",
+ __func__, se_state.new_tty_context, chk_tty_context);
goto skip_relabel;
}
@@ -173,6 +174,7 @@ relabel_tty(const char *ttyn, int ptyfd)
__func__);
debug_return_int(0);
}
+ sudo_debug_printf(SUDO_DEBUG_INFO, "%s: relabeling tty %s", __func__, ttyn);
/* If sudo is not allocating a pty for the command, open current tty. */
if (ptyfd == -1) {
@@ -345,8 +347,9 @@ bad:
}
/*
- * Set the exec and tty contexts in preparation for fork/exec.
- * Must run as root, before the uid change.
+ * Determine the exec and tty contexts in preparation for fork/exec.
+ * Must run as root, before forking the child process.
+ * Sets the tty context but not the exec context (which happens later).
* If ptyfd is not -1, it indicates we are running
* in a pty and do not need to reset std{in,out,err}.
* Returns 0 on success and -1 on failure.
diff -up ./src/sudo.c.tty2 ./src/sudo.c
--- ./src/sudo.c.tty2 2018-04-29 21:59:31.000000000 +0200
+++ ./src/sudo.c 2021-07-02 10:07:33.952025622 +0200
@@ -277,6 +277,7 @@ main(int argc, char *argv[], char *envp[
}
/* Setup command details and run command/edit. */
command_info_to_details(command_info, &command_details);
+ command_details.tty = user_details.tty;
command_details.argv = argv_out;
command_details.envp = user_env_out;
if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
diff -up ./src/sudo.h.tty2 ./src/sudo.h
--- ./src/sudo.h.tty2 2018-04-29 21:59:24.000000000 +0200
+++ ./src/sudo.h 2021-07-02 10:07:33.952025622 +0200
@@ -162,6 +162,7 @@ struct command_details {
const char *selinux_role;
const char *selinux_type;
const char *utmp_user;
+ const char *tty;
char **argv;
char **envp;
#ifdef HAVE_PRIV_SET