]> granicus.if.org Git - sudo/commitdiff
After opening a tty device, fstat() and error out if it is not
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 30 May 2017 16:44:11 +0000 (10:44 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 30 May 2017 16:44:11 +0000 (10:44 -0600)
a character device.

src/selinux.c

index c63869a46ffdd4032c88eecdcc09aba20a3b0d77..71bba949fa6b4d1d6df7b7282eb3abb94d5b7128 100644 (file)
@@ -29,6 +29,7 @@
 #ifdef HAVE_SELINUX
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -149,6 +150,7 @@ relabel_tty(const char *ttyn, int ptyfd)
 {
     security_context_t tty_con = NULL;
     security_context_t new_tty_con = NULL;
+    struct stat sb;
     int fd;
     debug_decl(relabel_tty, SUDO_DEBUG_SELINUX)
 
@@ -161,10 +163,15 @@ relabel_tty(const char *ttyn, int ptyfd)
     /* If sudo is not allocating a pty for the command, open current tty. */
     if (ptyfd == -1) {
        se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY|O_NONBLOCK);
-       if (se_state.ttyfd == -1) {
+       if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
            sudo_warn(U_("unable to open %s, not relabeling tty"), ttyn);
            goto bad;
        }
+       if (!S_ISCHR(sb.st_mode)) {
+           sudo_warn(U_("%s is not a character device, not relabeling tty"),
+               ttyn);
+           goto bad;
+       }
        (void)fcntl(se_state.ttyfd, F_SETFL,
            fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
     }
@@ -197,10 +204,15 @@ relabel_tty(const char *ttyn, int ptyfd)
     if (ptyfd != -1) {
        /* Reopen pty that was relabeled, std{in,out,err} are reset later. */
        se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY, 0);
-       if (se_state.ttyfd == -1) {
+       if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
            sudo_warn(U_("unable to open %s"), ttyn);
            goto bad;
        }
+       if (!S_ISCHR(sb.st_mode)) {
+           sudo_warn(U_("%s is not a character device, not relabeling tty"),
+               ttyn);
+           goto bad;
+       }
        if (dup2(se_state.ttyfd, ptyfd) == -1) {
            sudo_warn("dup2");
            goto bad;
@@ -209,10 +221,15 @@ relabel_tty(const char *ttyn, int ptyfd)
        /* Re-open tty to get new label and reset std{in,out,err} */
        close(se_state.ttyfd);
        se_state.ttyfd = open(ttyn, O_RDWR|O_NOCTTY|O_NONBLOCK);
-       if (se_state.ttyfd == -1) {
+       if (se_state.ttyfd == -1 || fstat(se_state.ttyfd, &sb) == -1) {
            sudo_warn(U_("unable to open %s"), ttyn);
            goto bad;
        }
+       if (!S_ISCHR(sb.st_mode)) {
+           sudo_warn(U_("%s is not a character device, not relabeling tty"),
+               ttyn);
+           goto bad;
+       }
        (void)fcntl(se_state.ttyfd, F_SETFL,
            fcntl(se_state.ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
        for (fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {