summaryrefslogtreecommitdiff
path: root/bin/systrace/systrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/systrace/systrace.c')
-rw-r--r--bin/systrace/systrace.c259
1 files changed, 183 insertions, 76 deletions
diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c
index 06dbfba3eee..1a0d4de8b05 100644
--- a/bin/systrace/systrace.c
+++ b/bin/systrace/systrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: systrace.c,v 1.20 2002/06/22 00:03:35 provos Exp $ */
+/* $OpenBSD: systrace.c,v 1.21 2002/07/09 15:22:27 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -55,9 +55,52 @@ int inherit = 0; /* Inherit policy to childs */
int automatic = 0; /* Do not run interactively */
int allow = 0; /* Allow all and generate */
int userpolicy = 1; /* Permit user defined policies */
+int noalias = 0; /* Do not do system call aliasing */
char *username = NULL; /* Username in automatic mode */
char cwd[MAXPATHLEN]; /* Current working directory of process */
+/*
+ * Generate human readable output and setup replacements if available.
+ */
+
+void
+make_output(char *output, size_t outlen, char *binname, pid_t pid,
+ int policynr, char *policy, int nfilters, char *emulation, char *name,
+ int code, struct intercept_tlq *tls, struct intercept_replace *repl)
+{
+ struct intercept_translate *tl;
+ char *p, *line;
+ int size, dorepl;
+
+ dorepl = tl != NULL && repl != NULL;
+
+ snprintf(output, outlen,
+ "%s, pid: %d(%d), policy: %s, filters: %d, syscall: %s-%s(%d)",
+ binname, pid, policynr, policy, nfilters,
+ emulation, name, code);
+
+ p = output + strlen(output);
+ size = outlen - strlen(output);
+
+ if (dorepl)
+ intercept_replace_init(repl);
+ TAILQ_FOREACH(tl, tls, next) {
+ if (!tl->trans_valid)
+ break;
+ line = intercept_translate_print(tl);
+ if (line == NULL)
+ continue;
+
+ snprintf(p, size, ", %s: %s", tl->name, line);
+ p = output + strlen(output);
+ size = sizeof(output) - strlen(output);
+
+ if (dorepl && tl->trans_size)
+ intercept_replace_add(repl, tl->off,
+ tl->trans_data, tl->trans_size);
+ }
+}
+
short
trans_cb(int fd, pid_t pid, int policynr,
char *name, int code, char *emulation,
@@ -65,12 +108,14 @@ trans_cb(int fd, pid_t pid, int policynr,
{
short action, future;
struct policy *policy;
- struct intercept_translate *tl;
struct intercept_pid *ipid;
struct intercept_replace repl;
+ struct intercept_tlq alitls;
+ struct intercept_translate alitl[SYSTRACE_MAXALIAS];
+ struct systrace_alias *alias = NULL;
struct filterq *pflq = NULL;
- char output[_POSIX2_LINE_MAX], *p, *line;
- int size;
+ char *binname = NULL;
+ char output[_POSIX2_LINE_MAX];
action = ICPOLICY_PERMIT;
@@ -81,38 +126,54 @@ trans_cb(int fd, pid_t pid, int policynr,
errx(1, "%s:%d: find %d", __func__, __LINE__,
policynr);
- if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL)
- errx(1, "%s:%d: no filter queue", __func__, __LINE__);
-
ipid = intercept_getpid(pid);
ipid->uflags = 0;
- snprintf(output, sizeof(output),
- "%s, pid: %d(%d), policy: %s, filters: %d, syscall: %s-%s(%d)",
- ipid->name != NULL ? ipid->name : policy->name, pid, policynr,
- policy->name, policy->nfilters, emulation, name, code);
- p = output + strlen(output);
- size = sizeof(output) - strlen(output);
+ binname = ipid->name != NULL ? ipid->name : policy->name;
- intercept_replace_init(&repl);
- TAILQ_FOREACH(tl, tls, next) {
- if (!tl->trans_valid)
- break;
- line = intercept_translate_print(tl);
- if (line == NULL)
- continue;
+ /* Required to set up replacements */
+ make_output(output, sizeof(output), binname, pid, policynr,
+ policy->name, policy->nfilters, emulation, name, code,
+ tls, &repl);
- snprintf(p, size, ", %s: %s", tl->name, line);
- p = output + strlen(output);
- size = sizeof(output) - strlen(output);
-
- if (tl->trans_size)
- intercept_replace_add(&repl, tl->off,
- tl->trans_data, tl->trans_size);
- }
+ if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL)
+ errx(1, "%s:%d: no filter queue", __func__, __LINE__);
action = filter_evaluate(tls, pflq, &ipid->uflags);
if (action != ICPOLICY_ASK)
goto replace;
+
+ /* Do aliasing here */
+ if (!noalias)
+ alias = systrace_find_alias(emulation, name);
+ if (alias != NULL) {
+ int i;
+
+ /* Set up variables for further filter actions */
+ tls = &alitls;
+ emulation = alias->aemul;
+ name = alias->aname;
+
+ /* Create an aliased list for filter_evaluate */
+ TAILQ_INIT(tls);
+ for (i = 0; i < alias->nargs; i++) {
+ memcpy(&alitl[i], alias->arguments[i],
+ sizeof(struct intercept_translate));
+ TAILQ_INSERT_TAIL(tls, &alitl[i], next);
+ }
+
+ if ((pflq = systrace_policyflq(policy,
+ alias->aemul, alias->aname)) == NULL)
+ errx(1, "%s:%d: no filter queue", __func__, __LINE__);
+
+ action = filter_evaluate(tls, pflq, &ipid->uflags);
+ if (action != ICPOLICY_ASK)
+ goto replace;
+
+ make_output(output, sizeof(output), binname, pid, policynr,
+ policy->name, policy->nfilters,
+ alias->aemul, alias->aname, code, tls, NULL);
+ }
+
if (policy->flags & POLICY_UNSUPERVISED) {
action = ICPOLICY_NEVER;
syslog(LOG_WARNING, "user: %s, prog: %s", username, output);
@@ -122,7 +183,7 @@ trans_cb(int fd, pid_t pid, int policynr,
action = filter_ask(tls, pflq, policynr, emulation, name,
output, &future, &ipid->uflags);
if (future != ICPOLICY_ASK)
- systrace_modifypolicy(fd, policynr, name, future);
+ filter_modifypolicy(fd, policynr, emulation, name, future);
if (policy->flags & POLICY_DETACHED) {
if (intercept_detach(fd, pid) == -1)
@@ -261,86 +322,128 @@ child_handler(int sig)
void
systrace_initcb(void)
{
+ struct systrace_alias *alias;
+ struct intercept_translate *tl;
+
X(intercept_init());
X(intercept_register_gencb(gen_cb, NULL));
X(intercept_register_sccb("native", "open", trans_cb, NULL));
- X(intercept_register_transfn("native", "open", 0));
- X(intercept_register_translation("native", "open", 1, &oflags));
+ tl = intercept_register_transfn("native", "open", 0);
+ intercept_register_translation("native", "open", 1, &oflags);
+ alias = systrace_new_alias("native", "open", "native", "fswrite");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("native", "connect", trans_cb, NULL));
- X(intercept_register_translation("native", "connect", 1,
- &ic_translate_connect));
+ intercept_register_translation("native", "connect", 1,
+ &ic_translate_connect);
X(intercept_register_sccb("native", "sendto", trans_cb, NULL));
- X(intercept_register_translation("native", "sendto", 4,
- &ic_translate_connect));
+ intercept_register_translation("native", "sendto", 4,
+ &ic_translate_connect);
X(intercept_register_sccb("native", "bind", trans_cb, NULL));
- X(intercept_register_translation("native", "bind", 1,
- &ic_translate_connect));
+ intercept_register_translation("native", "bind", 1,
+ &ic_translate_connect);
X(intercept_register_sccb("native", "execve", trans_cb, NULL));
- X(intercept_register_transfn("native", "execve", 0));
+ intercept_register_transfn("native", "execve", 0);
X(intercept_register_sccb("native", "stat", trans_cb, NULL));
- X(intercept_register_transfn("native", "stat", 0));
+ tl = intercept_register_transfn("native", "stat", 0);
+ alias = systrace_new_alias("native", "stat", "native", "fsread");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "lstat", trans_cb, NULL));
- X(intercept_register_translink("native", "lstat", 0));
+ tl = intercept_register_translink("native", "lstat", 0);
+ alias = systrace_new_alias("native", "lstat", "native", "fsread");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "unlink", trans_cb, NULL));
- X(intercept_register_transfn("native", "unlink", 0));
+ tl = intercept_register_transfn("native", "unlink", 0);
+ alias = systrace_new_alias("native", "unlink", "native", "fswrite");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "chown", trans_cb, NULL));
- X(intercept_register_transfn("native", "chown", 0));
- X(intercept_register_translation("native", "chown", 1, &uidt));
- X(intercept_register_translation("native", "chown", 2, &gidt));
+ intercept_register_transfn("native", "chown", 0);
+ intercept_register_translation("native", "chown", 1, &uidt);
+ intercept_register_translation("native", "chown", 2, &gidt);
X(intercept_register_sccb("native", "fchown", trans_cb, NULL));
- X(intercept_register_translation("native", "fchown", 0, &fdt));
- X(intercept_register_translation("native", "fchown", 1, &uidt));
- X(intercept_register_translation("native", "fchown", 2, &gidt));
+ intercept_register_translation("native", "fchown", 0, &fdt);
+ intercept_register_translation("native", "fchown", 1, &uidt);
+ intercept_register_translation("native", "fchown", 2, &gidt);
X(intercept_register_sccb("native", "chmod", trans_cb, NULL));
- X(intercept_register_transfn("native", "chmod", 0));
- X(intercept_register_translation("native", "chmod", 1, &modeflags));
+ intercept_register_transfn("native", "chmod", 0);
+ intercept_register_translation("native", "chmod", 1, &modeflags);
X(intercept_register_sccb("native", "readlink", trans_cb, NULL));
- X(intercept_register_translink("native", "readlink", 0));
+ tl = intercept_register_translink("native", "readlink", 0);
+ alias = systrace_new_alias("native", "readlink", "native", "fsread");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "chdir", trans_cb, NULL));
- X(intercept_register_transfn("native", "chdir", 0));
+ intercept_register_transfn("native", "chdir", 0);
X(intercept_register_sccb("native", "access", trans_cb, NULL));
- X(intercept_register_transfn("native", "access", 0));
+ tl = intercept_register_transfn("native", "access", 0);
+ alias = systrace_new_alias("native", "access", "native", "fsread");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "mkdir", trans_cb, NULL));
- X(intercept_register_transfn("native", "mkdir", 0));
+ tl = intercept_register_transfn("native", "mkdir", 0);
+ alias = systrace_new_alias("native", "mkdir", "native", "fswrite");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("native", "rmdir", trans_cb, NULL));
- X(intercept_register_transfn("native", "rmdir", 0));
+ tl = intercept_register_transfn("native", "rmdir", 0);
+ alias = systrace_new_alias("native", "rmdir", "native", "fswrite");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("native", "rename", trans_cb, NULL));
- X(intercept_register_transfn("native", "rename", 0));
- X(intercept_register_transfn("native", "rename", 1));
+ intercept_register_transfn("native", "rename", 0);
+ intercept_register_transfn("native", "rename", 1);
X(intercept_register_sccb("native", "symlink", trans_cb, NULL));
- X(intercept_register_transstring("native", "symlink", 0));
- X(intercept_register_translink("native", "symlink", 1));
+ intercept_register_transstring("native", "symlink", 0);
+ intercept_register_translink("native", "symlink", 1);
X(intercept_register_sccb("linux", "open", trans_cb, NULL));
- X(intercept_register_translink("linux", "open", 0));
- X(intercept_register_translation("linux", "open", 1, &linux_oflags));
+ tl = intercept_register_translink("linux", "open", 0);
+ intercept_register_translation("linux", "open", 1, &linux_oflags);
+ alias = systrace_new_alias("linux", "open", "linux", "fswrite");
+ systrace_alias_add_trans(alias, tl);
+
X(intercept_register_sccb("linux", "stat", trans_cb, NULL));
- X(intercept_register_translink("linux", "stat", 0));
+ tl = intercept_register_translink("linux", "stat", 0);
+ alias = systrace_new_alias("linux", "stat", "linux", "fsread");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "lstat", trans_cb, NULL));
- X(intercept_register_translink("linux", "lstat", 0));
+ tl = intercept_register_translink("linux", "lstat", 0);
+ alias = systrace_new_alias("linux", "lstat", "linux", "fsread");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "execve", trans_cb, NULL));
- X(intercept_register_translink("linux", "execve", 0));
+ intercept_register_translink("linux", "execve", 0);
X(intercept_register_sccb("linux", "access", trans_cb, NULL));
- X(intercept_register_translink("linux", "access", 0));
+ tl = intercept_register_translink("linux", "access", 0);
+ alias = systrace_new_alias("linux", "access", "linux", "fsread");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "symlink", trans_cb, NULL));
- X(intercept_register_transstring("linux", "symlink", 0));
- X(intercept_register_translink("linux", "symlink", 1));
+ intercept_register_transstring("linux", "symlink", 0);
+ intercept_register_translink("linux", "symlink", 1);
X(intercept_register_sccb("linux", "readlink", trans_cb, NULL));
- X(intercept_register_translink("linux", "readlink", 0));
+ tl = intercept_register_translink("linux", "readlink", 0);
+ alias = systrace_new_alias("linux", "readlink", "linux", "fsread");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "rename", trans_cb, NULL));
- X(intercept_register_translink("linux", "rename", 0));
- X(intercept_register_translink("linux", "rename", 1));
+ intercept_register_translink("linux", "rename", 0);
+ intercept_register_translink("linux", "rename", 1);
X(intercept_register_sccb("linux", "mkdir", trans_cb, NULL));
- X(intercept_register_translink("linux", "mkdir", 0));
+ tl = intercept_register_translink("linux", "mkdir", 0);
+ alias = systrace_new_alias("linux", "mkdir", "linux", "fswrite");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "rmdir", trans_cb, NULL));
- X(intercept_register_translink("linux", "rmdir", 0));
+ tl = intercept_register_translink("linux", "rmdir", 0);
+ alias = systrace_new_alias("linux", "rmdir", "linux", "fswrite");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "unlink", trans_cb, NULL));
- X(intercept_register_translink("linux", "unlink", 0));
+ tl = intercept_register_translink("linux", "unlink", 0);
+ alias = systrace_new_alias("linux", "unlink", "linux", "fswrite");
+ systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("linux", "chmod", trans_cb, NULL));
- X(intercept_register_translink("linux", "chmod", 0));
- X(intercept_register_translation("linux", "chmod", 1, &modeflags));
+ intercept_register_translink("linux", "chmod", 0);
+ intercept_register_translation("linux", "chmod", 1, &modeflags);
X(intercept_register_execcb(execres_cb, NULL));
}
@@ -349,7 +452,7 @@ void
usage(void)
{
fprintf(stderr,
- "Usage: systrace [-ait] [-g gui] [-f policy] [-p pid] command ...\n");
+ "Usage: systrace [-aituU] [-g gui] [-f policy] [-p pid] command ...\n");
exit(1);
}
@@ -410,7 +513,7 @@ main(int argc, char **argv)
pid_t pidattach = 0;
int usex11 = 1;
- while ((c = getopt(argc, argv, "aAitUg:f:p:")) != -1) {
+ while ((c = getopt(argc, argv, "aAituUg:f:p:")) != -1) {
switch (c) {
case 'a':
automatic = 1;
@@ -418,6 +521,9 @@ main(int argc, char **argv)
case 'A':
allow = 1;
break;
+ case 'u':
+ noalias = 1;
+ break;
case 'i':
inherit = 1;
break;
@@ -461,6 +567,7 @@ main(int argc, char **argv)
err(1, "signal");
/* Local initalization */
+ systrace_initalias();
systrace_initpolicy(filename);
systrace_initcb();