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