diff options
Diffstat (limited to 'bin/systrace/systrace.c')
-rw-r--r-- | bin/systrace/systrace.c | 259 |
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(); |