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