Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/systrace Mostly just a rewrite of intercept_run() so the...



details:   https://anonhg.NetBSD.org/src/rev/6ceebee93a02
branches:  trunk
changeset: 533551:6ceebee93a02
user:      atatat <atatat%NetBSD.org@localhost>
date:      Wed Jul 03 22:54:38 2002 +0000

description:
Mostly just a rewrite of intercept_run() so the arrangement of "child"
process and "parent" process is more conducive to policy generation.
Previously, tracing of a given program worked something like this:

        fork()
        if (child)
                execprogram()
        else
                dotracing()

That means that if you "systrace -a named", named would fork and
background itself, but you would never get your prompt back because
systrace didn't exit.  Now it works like this:

        fork()
        if (interactive)
                if (child)
                        execprogram()
                else
                        dotracing()
        else
                if (parent)
                        execprogram()
                else
                        fork()
                        if (parent)
                                exit(0)
                        setsid()
                        dotracing()

This makes it *much* easier to do automated policy generation for
tasks run from rc.d.  Or, for that matter, makes it much easier to use
systrace with tasks run from rc.d.

diffstat:

 bin/systrace/intercept.c |  117 +++++++++++++++++++++++++++++++++++++++++-----
 bin/systrace/systrace.c  |   33 ++++---------
 2 files changed, 114 insertions(+), 36 deletions(-)

diffs (250 lines):

diff -r 3ebcadbfd4ea -r 6ceebee93a02 bin/systrace/intercept.c
--- a/bin/systrace/intercept.c  Wed Jul 03 22:28:28 2002 +0000
+++ b/bin/systrace/intercept.c  Wed Jul 03 22:54:38 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intercept.c,v 1.2 2002/06/18 02:49:09 thorpej Exp $    */
+/*     $NetBSD: intercept.c,v 1.3 2002/07/03 22:54:38 atatat Exp $     */
 /*     $OpenBSD: intercept.c,v 1.5 2002/06/10 19:16:26 provos Exp $    */
 
 /*
@@ -31,11 +31,12 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: intercept.c,v 1.2 2002/06/18 02:49:09 thorpej Exp $");
+__RCSID("$NetBSD: intercept.c,v 1.3 2002/07/03 22:54:38 atatat Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/tree.h>
+#include <sys/wait.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -68,6 +69,8 @@
 static int pidcompare(struct intercept_pid *, struct intercept_pid *);
 static struct intercept_syscall *intercept_sccb_find(const char *,
     const char *);
+static void child_handler(int);
+static void sigusr1_handler(int);
 
 static SPLAY_HEAD(pidtree, intercept_pid) pids;
 static SPLAY_HEAD(sctree, intercept_syscall) scroot;
@@ -219,20 +222,76 @@
        return (0);
 }
 
+static void 
+child_handler(int sig)
+{
+       int s = errno, status;
+       extern int trfd;
+
+       if (signal(SIGCHLD, child_handler) == SIG_ERR) {
+               close(trfd);
+       } 
+
+       while (wait4(-1, &status, WNOHANG, NULL) > 0)
+               ;
+
+       errno = s;
+}
+
+static void
+sigusr1_handler(int signum)
+{
+       /* all we need to do is pretend to handle it */
+}
+
 pid_t
-intercept_run(int fd, char *path, char *const argv[])
+intercept_run(int bg, char *path, char *const argv[])
 {
-       pid_t pid;
+       sigset_t none, set, oset;
+       sig_t ohandler;
+       pid_t pid, cpid;
+       int status;
 
-       pid = fork();
-       if (pid == -1)
+       sigemptyset(&none);
+       sigemptyset(&set);
+       sigaddset(&set, SIGUSR1);
+       if (sigprocmask(SIG_BLOCK, &set, &oset) == -1)
+               err(1, "sigprocmask");
+       ohandler = signal(SIGUSR1, sigusr1_handler);
+       if (ohandler == SIG_ERR)
+               err(1, "signal");
+       pid = getpid();
+       cpid = fork();
+       if (cpid == -1)
                return (-1);
-       if (pid == 0) {
-               /* Needs to be closed */
-               close(fd);
 
-               /* Stop myself */
-               raise(SIGSTOP);
+       /*
+        * If the systrace process should be in the background and we're
+        * the parent, or vice versa.
+        */
+       if ((bg && cpid != 0) || (!bg && cpid == 0)) {
+               if (bg) {
+                       /* Wait for child to "detach" */
+                       cpid = wait(&status);
+                       if (cpid == -1)
+                               err(1, "wait");
+                       if (status != 0)
+                               errx(1, "wait: child gave up");
+               }
+
+               /* Sleep */
+               (void)sigsuspend(&none);
+
+               /*
+                * Woken up, restore signal handling state.
+                *
+                * Note that there is either no child or we have no idea
+                * what pid it might have at this point.  If we fail.
+                */
+               if (signal(SIGUSR1, ohandler) == SIG_ERR)
+                       err(1, "signal");
+               if (sigprocmask(SIG_SETMASK, &oset, NULL) == -1)
+                       err(1, "sigprocmask");
 
                execvp(path, argv);
 
@@ -240,9 +299,38 @@
                err(1, "execvp");
        }
 
-       sleep(1); /* XXX */
+       /* Setup done, restore signal handling state */
+       if (signal(SIGUSR1, ohandler) == SIG_ERR) {
+               if (!bg)
+                       kill(cpid, SIGKILL);
+               err(1, "signal");
+       }
+       if (sigprocmask(SIG_SETMASK, &oset, NULL) == -1) {
+               if (!bg)
+                       kill(cpid, SIGKILL);
+               err(1, "sigprocmask");
+       }
+
+       if (bg) {
+               pid_t c2;
 
-       return (pid);
+               c2 = fork();
+               if (c2 == -1)
+                       err(1, "fork");
+               if (c2 != 0)
+                       exit(0);
+               if (setsid() == -1)
+                       err(1, "setsid");
+       }
+       else {
+               if (signal(SIGCHLD, child_handler) == SIG_ERR) {
+                       warn("signal");
+                       kill(cpid, SIGKILL);
+                       exit(1);
+               }
+       }
+
+       return (bg ? pid : cpid);
 }
 
 int
@@ -304,6 +392,9 @@
        if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
                warn("fcntl(O_NONBLOCK)");
 
+       if (fcntl(fd, F_SETFD, 1) == -1)
+               warn("fcntl(F_SETFD)");
+
        return (fd);
 }
 
diff -r 3ebcadbfd4ea -r 6ceebee93a02 bin/systrace/systrace.c
--- a/bin/systrace/systrace.c   Wed Jul 03 22:28:28 2002 +0000
+++ b/bin/systrace/systrace.c   Wed Jul 03 22:54:38 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: systrace.c,v 1.2 2002/06/18 21:22:45 thorpej Exp $     */
+/*     $NetBSD: systrace.c,v 1.3 2002/07/03 22:54:38 atatat Exp $      */
 /*     $OpenBSD: systrace.c,v 1.16 2002/06/12 22:14:51 provos Exp $    */
 
 /*
@@ -31,7 +31,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: systrace.c,v 1.2 2002/06/18 21:22:45 thorpej Exp $");
+__RCSID("$NetBSD: systrace.c,v 1.3 2002/07/03 22:54:38 atatat Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -67,7 +67,6 @@
 static short gen_cb(int, pid_t, int, const char *, int, const char *, void *,
     int, void *);
 static void execres_cb(int, pid_t, int, const char *, const char *, void *);
-static void child_handler(int);
 static void systrace_initcb(void);
 static void usage(void);
 static int requestor_start(char *);
@@ -242,21 +241,6 @@
        fprintf(stderr, "Terminating %d: %s\n", pid, name);
 }
 
-static void
-child_handler(int sig)
-{
-       int s = errno, status;
-
-       if (signal(SIGCHLD, child_handler) == SIG_ERR) {
-               close(trfd);
-       }
-
-       while (wait4(-1, &status, WNOHANG, NULL) > 0)
-               ;
-
-       errno = s;
-}
-
 #define X(x)   if ((x) == -1) \
        err(1, "%s:%d: intercept failed", __func__, __LINE__)
 
@@ -530,9 +514,6 @@
        if (getcwd(cwd, sizeof(cwd)) == NULL)
                err(1, "getcwd");
 
-       if (signal(SIGCHLD, child_handler) == SIG_ERR)
-               err(1, "signal");
-
        /* Local initalization */
        systrace_initpolicy(filename);
        systrace_initcb();
@@ -549,14 +530,20 @@
                        args[i] = argv[i];
                args[i] = NULL;
 
-               trpid = intercept_run(trfd, args[0], args);
+               /*
+                * We will run in the background if using X11, or
+                * doing fixed policy enforcement, or doing automatic
+                * policy generation.
+                */
+               trpid = intercept_run(usex11 || automatic || allow,
+                   args[0], args);
                if (trpid == -1)
                        err(1, "fork");
 
                if (intercept_attach(trfd, trpid) == -1)
                        err(1, "attach");
 
-               if (kill(trpid, SIGCONT) == -1)
+               if (kill(trpid, SIGUSR1) == -1)
                        err(1, "kill");
        } else {
                /* Attach to a running command */



Home | Main Index | Thread Index | Old Index