]> granicus.if.org Git - sudo/commitdiff
Make SELinux support compile again. Needs more work to be complete.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 24 May 2010 22:18:50 +0000 (18:18 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 24 May 2010 22:18:50 +0000 (18:18 -0400)
src/script.c
src/selinux.c
src/sudo.h

index 42e57ee7e019f7fe895758d429af7510f3ff92f2..606dd61c4d6eaa5346ad2f64b36a5ed993b7834c 100644 (file)
@@ -136,6 +136,8 @@ static void sync_ttysize(int src, int dst);
 static void deliver_signal(pid_t pid, int signo);
 static int safe_close(int fd);
 
+extern struct user_details user_details; /* XXX */
+
 void
 script_setup(uid_t uid)
 {
@@ -500,15 +502,25 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
     log_io = !tq_empty(&io_plugins);
 
 #ifdef HAVE_SELINUX
-    rbac_enabled = is_selinux_enabled() > 0 && user_role != NULL;
+    rbac_enabled = is_selinux_enabled() > 0 && details->selinux_role != NULL;
     if (rbac_enabled) {
-       selinux_prefork(user_role, user_type, script_fds[SFD_SLAVE]);
        if (log_io) {
+           selinux_prefork(details->selinux_role, details->selinux_type,
+               script_fds[SFD_SLAVE]);
            /* Re-open slave fd after it has been relabeled */
            close(script_fds[SFD_SLAVE]);
            script_fds[SFD_SLAVE] = open(slavename, O_RDWR|O_NOCTTY, 0);
            if (script_fds[SFD_SLAVE] == -1)
            error(1, "cannot open %s", slavename);
+       } else if (user_details.tty != NULL) {
+           /* XXX - push this down into selinux_prefork */
+           int ttyfd = open(user_details.tty, O_RDWR|O_NONBLOCK);
+           if (ttyfd == -1)
+               error(1, "unable to open %s", user_details.tty);
+           (void)fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NONBLOCK);
+           selinux_prefork(details->selinux_role, details->selinux_type,
+               ttyfd);
+           close(ttyfd);
        }
     }
 #endif
@@ -863,6 +875,15 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
            }
        }
     }
+
+#ifdef HAVE_SELINUX
+    /* If I/O logging the label was on the pty which is now gone. */
+    if (rbac_enabled && !log_io) {
+       if (selinux_restore_tty(user_details.tty) != 0)
+           warningx("unable to restore tty label");
+    }
+#endif
+
     efree(fdsr);
     efree(fdsw);
     while ((iob = iobufs) != NULL) {
index c1c97658f33498ef9a849070c8f17147f2fbaec2..a59648447913bb282674dcd9d898822ed3554708 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009-2010 Todd C. Miller <Todd.Miller@courtesan.com>
  * Copyright (c) 2008 Dan Walsh <dwalsh@redhat.com>
  *
  * Borrowed heavily from newrole source code
@@ -58,38 +59,41 @@ static int enforcing;
  * This function attempts to revert the relabeling done to the tty.
  * fd             - referencing the opened ttyn
  * ttyn                   - name of tty to restore
- * tty_context    - original context of the tty
- * new_tty_context - context tty was relabeled to
  *
  * Returns zero on success, non-zero otherwise
  */
-static int
-restore_tty_label(int fd, const char *ttyn, security_context_t tty_context,
-    security_context_t new_tty_context)
+/* XXX - should be called as part of cleanup() */
+int
+selinux_restore_tty(const char *ttyn)
 {
-    int rc = 0;
+    int fd, rc = 0;
     security_context_t chk_tty_context = NULL;
 
-    if (!ttyn)
-           goto skip_relabel;
+    if (ttyn == NULL || new_tty_context == NULL)
+       goto skip_relabel;
 
-    if (!new_tty_context)
-           goto skip_relabel;
+    /* Re-open TTY descriptor */
+    fd = open(ttyn, O_RDWR | O_NONBLOCK);
+    if (fd == -1)
+       error(EXIT_FAILURE, "unable to open %s", ttyn);
+    (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
 
     /* Verify that the tty still has the context set by sudo. */
     if ((rc = fgetfilecon(fd, &chk_tty_context)) < 0) {
-           warning("unable to fgetfilecon %s", ttyn);
-           goto skip_relabel;
+       warning("unable to fgetfilecon %s", ttyn);
+       goto skip_relabel;
     }
 
     if ((rc = strcmp(chk_tty_context, new_tty_context))) {
-           warningx("%s changed labels.", ttyn);
-           goto skip_relabel;
+       warningx("%s changed labels.", ttyn);
+       goto skip_relabel;
     }
 
     if ((rc = fsetfilecon(fd, tty_context)) < 0)
        warning("unable to restore context for %s", ttyn);
 
+    close(fd);
+
 skip_relabel:
     freecon(chk_tty_context);
     return(rc);
@@ -146,7 +150,7 @@ error:
  * specified role and type.
  */
 security_context_t
-get_exec_context(security_context_t old_context, char *role, char *type)
+get_exec_context(security_context_t old_context, const char *role, const char *type)
 {
     security_context_t new_context = NULL;
     context_t context = NULL;
@@ -211,7 +215,7 @@ error:
  * Set the tty context in preparation for fork/exec.
  */
 void
-selinux_prefork(char *role, char *type, int ttyfd)
+selinux_prefork(const char *role, const char *type, int ttyfd)
 {
     /* Store the caller's SID in old_context. */
     if (getprevcon(&old_context))
@@ -228,17 +232,20 @@ selinux_prefork(char *role, char *type, int ttyfd)
     if (!new_context)
        error(EXIT_FAILURE, "unable to get exec context");
     
-    ttyfd = relabel_tty(ttyfd, new_context, &tty_context,
-       &new_tty_context, enforcing);
-    if (ttyfd < 0)
-       error(EXIT_FAILURE, "unable to setup tty context for %s", new_context);
-
+    if (ttyfd != -1) {
+       ttyfd = relabel_tty(ttyfd, new_context, &tty_context,
+           &new_tty_context, enforcing);
+       if (ttyfd < 0)
+           error(EXIT_FAILURE, "unable to setup tty context for %s",
+               new_context);
 #ifdef DEBUG
-    warningx("your old tty context is %s", tty_context);
-    warningx("your new tty context is %s", new_tty_context);
+       warningx("your old tty context is %s", tty_context);
+       warningx("your new tty context is %s", new_tty_context);
 #endif
+    }
 }
 
+/* XXX - pass in ttyn for audit support */
 void
 selinux_execve(const char *path, char *argv[], char *envp[])
 {
@@ -255,7 +262,7 @@ selinux_execve(const char *path, char *argv[], char *envp[])
     }
 
 #ifdef WITH_AUDIT
-    if (send_audit_message(1, old_context, new_context, user_ttypath)) 
+    if (send_audit_message(1, old_context, new_context, ttyn)) 
        return;
 #endif
 
@@ -269,6 +276,7 @@ selinux_execve(const char *path, char *argv[], char *envp[])
     warning("%s", path);
 }
 
+#if 0 /* XXX */
 /* 
  * If the program is being run with a different security context we
  * need to go through an intermediary process for the transition to
@@ -301,7 +309,7 @@ selinux_exec(char *role, char *type, char **argv)
     if (childPid < 0) {
        /* fork failed, no child to worry about */
        warning("unable to fork");
-       if (restore_tty_label(ttyfd, user_ttypath, tty_context, new_tty_context))
+       if (selinux_restore_tty(user_ttypath);
            warningx("unable to restore tty label");
        exit(EXIT_FAILURE);
     } else if (childPid) {
@@ -316,7 +324,7 @@ selinux_exec(char *role, char *type, char **argv)
        if (pid == -1)
            error(EXIT_FAILURE, "waitpid");
        
-       if (restore_tty_label(ttyfd, user_ttypath, tty_context, new_tty_context))
+       if (selinux_restore_tty(user_ttypath);
            errorx(EXIT_FAILURE, "unable to restore tty label");
 
        /* Preserve child exit status. */
@@ -348,3 +356,4 @@ selinux_exec(char *role, char *type, char **argv)
 error:
     _exit(EXIT_FAILURE);
 }
+#endif /* XXX */
index 27e0c24178caefa1cd1263a6044cd2c910bec236..6203fb85c570650b6a8aed4d928000dcfc9792d8 100644 (file)
@@ -202,6 +202,11 @@ void usage(int) __attribute__((__noreturn__));
 /* gettime.c */
 int gettime(struct timeval *);
 
+/* selinux.c */
+void selinux_execve(const char *path, char *argv[], char *envp[]);
+void selinux_prefork(const char *role, const char *type, int ttyfd);
+int selinux_restore_tty(const char *ttyn);
+
 #ifndef errno
 extern int errno;
 #endif