summaryrefslogtreecommitdiff
path: root/bin/systrace
diff options
context:
space:
mode:
Diffstat (limited to 'bin/systrace')
-rw-r--r--bin/systrace/intercept.c83
-rw-r--r--bin/systrace/intercept.h4
-rw-r--r--bin/systrace/systrace.c24
3 files changed, 92 insertions, 19 deletions
diff --git a/bin/systrace/intercept.c b/bin/systrace/intercept.c
index c39fc673e01..3580167fe04 100644
--- a/bin/systrace/intercept.c
+++ b/bin/systrace/intercept.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intercept.c,v 1.11 2002/07/09 15:22:27 provos Exp $ */
+/* $OpenBSD: intercept.c,v 1.12 2002/07/09 20:46:18 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -213,20 +213,65 @@ intercept_register_execcb(void (*cb)(int, pid_t, int, char *, char *, void *), v
return (0);
}
+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, int fd, char *path, char *const argv[])
{
- pid_t pid;
-
- pid = fork();
- if (pid == -1)
+ sigset_t none, set, oset;
+ sig_t ohandler;
+ pid_t pid, cpid;
+ int status;
+
+ /* Block signals so that timeing on signal delivery does not matter */
+ 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) {
+
+ /*
+ * If the systrace process should be in the background and we're
+ * the parent, or vice versa.
+ */
+ if ((!bg && cpid == 0) || (bg && cpid != 0)) {
/* Needs to be closed */
close(fd);
- /* Stop myself */
- raise(SIGSTOP);
+ 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 */
+ 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);
@@ -234,7 +279,25 @@ intercept_run(int fd, char *path, char *const argv[])
err(1, "execvp");
}
- sleep(1); /* XXX */
+ /* Choose the pid of the systraced process */
+ pid = bg ? pid : cpid;
+
+ /* Setup done, restore signal handling state */
+ if (signal(SIGUSR1, ohandler) == SIG_ERR) {
+ kill(pid, SIGKILL);
+ err(1, "signal");
+ }
+ if (sigprocmask(SIG_SETMASK, &oset, NULL) == -1) {
+ kill(pid, SIGKILL);
+ err(1, "sigprocmask");
+ }
+
+ if (bg) {
+ if (daemon(0, 0) == -1) {
+ kill(pid, SIGKILL);
+ err(1, "daemon");
+ }
+ }
return (pid);
}
diff --git a/bin/systrace/intercept.h b/bin/systrace/intercept.h
index d1bd4cc3ab8..029ac2b026f 100644
--- a/bin/systrace/intercept.h
+++ b/bin/systrace/intercept.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intercept.h,v 1.4 2002/07/09 15:22:27 provos Exp $ */
+/* $OpenBSD: intercept.h,v 1.5 2002/07/09 20:46:18 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -110,7 +110,7 @@ struct intercept_replace {
TAILQ_HEAD(intercept_tlq, intercept_translate);
int intercept_init(void);
-pid_t intercept_run(int, char *, char * const *);
+pid_t intercept_run(int, int, char *, char * const *);
int intercept_open(void);
int intercept_attach(int, pid_t);
int intercept_attachpid(int, pid_t, char *);
diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c
index 1a0d4de8b05..f3224220093 100644
--- a/bin/systrace/systrace.c
+++ b/bin/systrace/systrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: systrace.c,v 1.21 2002/07/09 15:22:27 provos Exp $ */
+/* $OpenBSD: systrace.c,v 1.22 2002/07/09 20:46:18 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -512,6 +512,7 @@ main(int argc, char **argv)
char *guipath = _PATH_XSYSTRACE;
pid_t pidattach = 0;
int usex11 = 1;
+ int background;
while ((c = getopt(argc, argv, "aAituUg:f:p:")) != -1) {
switch (c) {
@@ -563,9 +564,6 @@ main(int argc, char **argv)
if (getcwd(cwd, sizeof(cwd)) == NULL)
err(1, "getcwd");
- if (signal(SIGCHLD, child_handler) == SIG_ERR)
- err(1, "signal");
-
/* Local initalization */
systrace_initalias();
systrace_initpolicy(filename);
@@ -574,6 +572,9 @@ main(int argc, char **argv)
if ((fd = intercept_open()) == -1)
exit(1);
+ /* See if we can run the systrace process in the background */
+ background = usex11 || automatic || allow;
+
if (pidattach == 0) {
/* Run a command and attach to it */
if ((args = malloc((argc + 1) * sizeof(char *))) == NULL)
@@ -583,22 +584,31 @@ main(int argc, char **argv)
args[i] = argv[i];
args[i] = NULL;
- pid = intercept_run(fd, args[0], args);
+ pid = intercept_run(background, fd, args[0], args);
if (pid == -1)
err(1, "fork");
if (intercept_attach(fd, pid) == -1)
err(1, "attach");
- if (kill(pid, SIGCONT) == -1)
+ if (kill(pid, SIGUSR1) == -1)
err(1, "kill");
} else {
- /* Attach to a running command */
+ pid_t cpid;
+ /* Attach to a running command */
if (intercept_attachpid(fd, pidattach, argv[0]) == -1)
err(1, "attachpid");
+
+ if (background) {
+ if (daemon(0, 0) == -1)
+ err(1, "daemon");
+ }
}
+ if (signal(SIGCHLD, child_handler) == SIG_ERR)
+ err(1, "signal");
+
/* Start the policy gui if necessary */
if (usex11 && !automatic && !allow)
requestor_start(guipath);