diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2002-07-09 15:22:28 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2002-07-09 15:22:28 +0000 |
commit | a130bc95bf8f7bf341fce48bb49ae75d32acdc38 (patch) | |
tree | 73e20d2459d45f601c39ee4160ebc062076a0774 /bin/systrace | |
parent | 4fd5221df774f98cc0ecff162ebc6476cd362c21 (diff) |
support for system call aliasing. stat/fstat/readlink/access etc... gets
grouped into fsread, unlink/rmdir/mkdir goes to fswrite. open switches
back between fsread and fswrite depending on oflags parameter.
Diffstat (limited to 'bin/systrace')
-rw-r--r-- | bin/systrace/Makefile | 4 | ||||
-rw-r--r-- | bin/systrace/alias.c | 196 | ||||
-rw-r--r-- | bin/systrace/filter.c | 38 | ||||
-rw-r--r-- | bin/systrace/intercept.c | 15 | ||||
-rw-r--r-- | bin/systrace/intercept.h | 6 | ||||
-rw-r--r-- | bin/systrace/systrace-translate.c | 18 | ||||
-rw-r--r-- | bin/systrace/systrace.1 | 6 | ||||
-rw-r--r-- | bin/systrace/systrace.c | 259 | ||||
-rw-r--r-- | bin/systrace/systrace.h | 40 |
9 files changed, 485 insertions, 97 deletions
diff --git a/bin/systrace/Makefile b/bin/systrace/Makefile index 09dd506e191..bbe3c64447b 100644 --- a/bin/systrace/Makefile +++ b/bin/systrace/Makefile @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile,v 1.4 2002/06/05 17:34:56 mickey Exp $ +# $OpenBSD: Makefile,v 1.5 2002/07/09 15:22:27 provos Exp $ PROG= systrace CFLAGS+= -I. SRCS= filter.c intercept-translate.c intercept.c \ openbsd-syscalls.c util.c \ policy.c systrace-errno.h systrace-error.c \ - systrace-translate.c systrace.c \ + systrace-translate.c systrace.c alias.c \ parse.y lex.l CLEANFILES+= parse.c lex.c y.tab.h diff --git a/bin/systrace/alias.c b/bin/systrace/alias.c new file mode 100644 index 00000000000..1b2e6eb6630 --- /dev/null +++ b/bin/systrace/alias.c @@ -0,0 +1,196 @@ +/* $OpenBSD: alias.c,v 1.1 2002/07/09 15:22:27 provos Exp $ */ +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/tree.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <grp.h> +#include <stdio.h> +#include <fcntl.h> +#include <ctype.h> +#include <err.h> + +#include "intercept.h" +#include "systrace.h" + +static SPLAY_HEAD(alitr, systrace_alias) aliasroot; +static SPLAY_HEAD(revtr, systrace_revalias) revroot; + +int +aliascompare(struct systrace_alias *a, struct systrace_alias *b) +{ + int diff; + + diff = strcmp(a->emulation, b->emulation); + if (diff) + return (diff); + return (strcmp(a->name, b->name)); +} + +int +revcompare(struct systrace_revalias *a, struct systrace_revalias *b) +{ + int diff; + + diff = strcmp(a->emulation, b->emulation); + if (diff) + return (diff); + return (strcmp(a->name, b->name)); +} + +SPLAY_PROTOTYPE(alitr, systrace_alias, node, aliascompare); +SPLAY_GENERATE(alitr, systrace_alias, node, aliascompare); + +SPLAY_PROTOTYPE(revtr, systrace_revalias, node, revcompare); +SPLAY_GENERATE(revtr, systrace_revalias, node, revcompare); + +int +systrace_initalias(void) +{ + SPLAY_INIT(&aliasroot); + SPLAY_INIT(&revroot); + + return (0); +} + +struct systrace_alias * +systrace_find_alias(char *emulation, char *name) +{ + struct systrace_alias tmp; + + strlcpy(tmp.emulation, emulation, sizeof(tmp.emulation)); + strlcpy(tmp.name, name, sizeof(tmp.name)); + + return (SPLAY_FIND(alitr, &aliasroot, &tmp)); +} + +struct systrace_revalias * +systrace_find_reverse(char *emulation, char *name) +{ + struct systrace_revalias tmp; + + strlcpy(tmp.emulation, emulation, sizeof(tmp.emulation)); + strlcpy(tmp.name, name, sizeof(tmp.name)); + + return (SPLAY_FIND(revtr, &revroot, &tmp)); +} + +struct systrace_revalias * +systrace_reverse(char *emulation, char *name) +{ + struct systrace_revalias tmp, *reverse; + + strlcpy(tmp.emulation, emulation, sizeof(tmp.emulation)); + strlcpy(tmp.name, name, sizeof(tmp.name)); + + reverse = SPLAY_FIND(revtr, &revroot, &tmp); + if (reverse != NULL) + return (reverse); + + reverse = calloc(1, sizeof(struct systrace_alias)); + if (reverse == NULL) + err(1, "%s: %s-%s: malloc", __func__, emulation, name); + + strlcpy(reverse->emulation, emulation, sizeof(reverse->emulation)); + strlcpy(reverse->name, name, sizeof(reverse->name)); + + TAILQ_INIT(&reverse->revl); + + if (SPLAY_INSERT(revtr, &revroot, reverse) != NULL) + errx(1, "%s: %s-%s: double revalias", + __func__, emulation, name); + + return (reverse); +} + +struct systrace_alias * +systrace_new_alias(char *emulation, char *name, char *aemul, char *aname) +{ + struct systrace_alias *alias; + struct systrace_revalias *reverse; + + alias = malloc(sizeof(struct systrace_alias)); + if (alias == NULL) + err(1, "%s: %s-%s: malloc", __func__, emulation, name); + + strlcpy(alias->emulation, emulation, sizeof(alias->emulation)); + strlcpy(alias->name, name, sizeof(alias->name)); + strlcpy(alias->aemul, aemul, sizeof(alias->aemul)); + strlcpy(alias->aname, aname, sizeof(alias->aname)); + alias->nargs = 0; + + if (SPLAY_INSERT(alitr, &aliasroot, alias) != NULL) + errx(1, "%s: %s-%s: double alias", __func__, emulation, name); + + reverse = systrace_reverse(aemul, aname); + alias->reverse = reverse; + TAILQ_INSERT_TAIL(&reverse->revl, alias, next); + + return (alias); +} + +void +systrace_switch_alias(char *emulation, char *name, char *aemul, char *aname) +{ + struct systrace_alias *alias; + struct systrace_revalias *reverse; + + if ((alias = systrace_find_alias(emulation, name)) == NULL) + errx(1, "%s: unknown alias %s-%s", __func__, emulation, name); + + /* Switch to a different alias */ + reverse = alias->reverse; + TAILQ_REMOVE(&reverse->revl, alias, next); + + strlcpy(alias->aemul, aemul, sizeof(alias->aemul)); + strlcpy(alias->aname, aname, sizeof(alias->aname)); + + reverse = systrace_reverse(aemul, aname); + alias->reverse = reverse; + TAILQ_INSERT_TAIL(&reverse->revl, alias, next); +} + +/* Add an already translated argument to this alias */ + +void +systrace_alias_add_trans(struct systrace_alias *alias, + struct intercept_translate *tl) +{ + if (alias->nargs >= SYSTRACE_MAXALIAS) + errx(1, "%s: too many arguments", __func__); + + alias->arguments[alias->nargs++] = tl; +} diff --git a/bin/systrace/filter.c b/bin/systrace/filter.c index d45af898ff2..1f9743b9938 100644 --- a/bin/systrace/filter.c +++ b/bin/systrace/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.13 2002/06/19 16:31:07 provos Exp $ */ +/* $OpenBSD: filter.c,v 1.14 2002/07/09 15:22:27 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -46,6 +46,7 @@ #include "systrace.h" extern int allow; +extern int noalias; extern int connected; extern char cwd[]; @@ -256,6 +257,34 @@ filter_parse_simple(char *rule, short *paction, short *pfuture) return (NULL); } +void +filter_modifypolicy(int fd, int policynr, char *emulation, char *name, + short future) +{ + struct systrace_revalias *reverse = NULL; + + if (!noalias) + reverse = systrace_find_reverse(emulation, name); + if (reverse == NULL) { + if (systrace_modifypolicy(fd, policynr, name, future) == -1) + errx(1, "%s:%d: modify policy for %s-%s", + __func__, __LINE__, emulation, name); + } else { + struct systrace_alias *alias; + + /* For every system call associated with this alias + * set the permanent in-kernel policy. + */ + TAILQ_FOREACH(alias, &reverse->revl, next) { + if(systrace_modifypolicy(fd, policynr, + alias->name, future) == -1) + errx(1, "%s:%d: modify policy for %s-%s", + __func__, __LINE__, + emulation, alias->name); + } + } +} + int filter_prepolicy(int fd, struct policy *policy) { @@ -285,11 +314,8 @@ filter_prepolicy(int fd, struct policy *policy) filter->name); TAILQ_INSERT_TAIL(fls, parsed, next); } else { - res = systrace_modifypolicy(fd, policy->policynr, - filter->name, future); - if (res == -1) - errx(1, "%s:%d: modify policy for \"%s\"", - __func__, __LINE__, filter->rule); + filter_modifypolicy(fd, policy->policynr, + policy->emulation, filter->name, future); } filter_policyrecord(policy, parsed, policy->emulation, filter->name, filter->rule); diff --git a/bin/systrace/intercept.c b/bin/systrace/intercept.c index 7c5c025f9cc..c39fc673e01 100644 --- a/bin/systrace/intercept.c +++ b/bin/systrace/intercept.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intercept.c,v 1.10 2002/07/09 13:07:42 dhartmei Exp $ */ +/* $OpenBSD: intercept.c,v 1.11 2002/07/09 15:22:27 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -122,7 +122,7 @@ intercept_sccb_find(char *emulation, char *name) return (SPLAY_FIND(sctree, &scroot, &tmp)); } -int +struct intercept_translate * intercept_register_translation(char *emulation, char *name, int offset, struct intercept_translate *tl) { @@ -130,22 +130,25 @@ intercept_register_translation(char *emulation, char *name, int offset, struct intercept_translate *tlnew; if (offset >= INTERCEPT_MAXSYSCALLARGS) - return (-1); + errx(1, "%s: %s-%s: offset too large", + __func__, emulation, name); tmp = intercept_sccb_find(emulation, name); if (tmp == NULL) - return (-1); + errx(1, "%s: %s-%s: can't find call back", + __func__, emulation, name); tlnew = malloc(sizeof(struct intercept_translate)); if (tlnew == NULL) - return (-1); + err(1, "%s: %s-%s: malloc", + __func__, emulation, name); memcpy(tlnew, tl, sizeof(struct intercept_translate)); tlnew->off = offset; TAILQ_INSERT_TAIL(&tmp->tls, tlnew, next); - return (0); + return (tlnew); } void * diff --git a/bin/systrace/intercept.h b/bin/systrace/intercept.h index 3c2c6c0d0da..d1bd4cc3ab8 100644 --- a/bin/systrace/intercept.h +++ b/bin/systrace/intercept.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intercept.h,v 1.3 2002/06/21 15:26:06 provos Exp $ */ +/* $OpenBSD: intercept.h,v 1.4 2002/07/09 15:22:27 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -133,8 +133,8 @@ void *intercept_sccb_cbarg(char *, char *); int intercept_register_gencb(short (*)(int, pid_t, int, char *, int, char *, void *, int, void *), void *); int intercept_register_execcb(void (*)(int, pid_t, int, char *, char *, void *), void *); -int intercept_register_translation(char *, char *, int, - struct intercept_translate *); +struct intercept_translate *intercept_register_translation(char *, char *, + int, struct intercept_translate *); int intercept_translate(struct intercept_translate *, int, pid_t, int, void *, int); char *intercept_translate_print(struct intercept_translate *); diff --git a/bin/systrace/systrace-translate.c b/bin/systrace/systrace-translate.c index 7b07f641a0d..7917e20f11c 100644 --- a/bin/systrace/systrace-translate.c +++ b/bin/systrace/systrace-translate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace-translate.c,v 1.2 2002/06/04 19:09:45 provos Exp $ */ +/* $OpenBSD: systrace-translate.c,v 1.3 2002/07/09 15:22:27 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -55,11 +55,13 @@ print_oflags(char *buf, size_t buflen, struct intercept_translate *tl) { char str[32], *p; int flags = (int)tl->trans_addr; + int isread = 0; p = str; switch (flags & O_ACCMODE) { case O_RDONLY: strcpy(p, "ro"); + isread = 1; break; case O_WRONLY: strcpy(p, "wo"); @@ -72,6 +74,12 @@ print_oflags(char *buf, size_t buflen, struct intercept_translate *tl) break; } + /* XXX - Open handling of alias */ + if (isread) + systrace_switch_alias("native", "open", "native", "fsread"); + else + systrace_switch_alias("native", "open", "native", "fswrite"); + p += 2; FL(O_NONBLOCK, 'n'); @@ -91,11 +99,13 @@ linux_print_oflags(char *buf, size_t buflen, struct intercept_translate *tl) { char str[32], *p; int flags = (int)tl->trans_addr; + int isread = 0; p = str; switch (flags & LINUX_O_ACCMODE) { case LINUX_O_RDONLY: strcpy(p, "ro"); + isread = 1; break; case LINUX_O_WRONLY: strcpy(p, "wo"); @@ -108,6 +118,12 @@ linux_print_oflags(char *buf, size_t buflen, struct intercept_translate *tl) break; } + /* XXX - Open handling of alias */ + if (isread) + systrace_switch_alias("linux", "open", "linux", "fsread"); + else + systrace_switch_alias("linux", "open", "linux", "fswrite"); + p += 2; FL(LINUX_O_APPEND, 'a'); diff --git a/bin/systrace/systrace.1 b/bin/systrace/systrace.1 index 62895fd3561..e28abe64c31 100644 --- a/bin/systrace/systrace.1 +++ b/bin/systrace/systrace.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: systrace.1,v 1.20 2002/06/21 15:37:56 provos Exp $ +.\" $OpenBSD: systrace.1,v 1.21 2002/07/09 15:22:27 provos Exp $ .\" .\" Copyright 2002 Niels Provos <provos@citi.umich.edu> .\" All rights reserved. @@ -38,7 +38,7 @@ .Nd generates and enforces system call policies .Sh SYNOPSIS .Nm systrace -.Op Fl aAitU +.Op Fl aAituU .Op Fl g Ar gui .Op Fl f Ar file .Op Fl p Ar pid @@ -62,6 +62,8 @@ An operation not covered by policy is denied and logged via Automatically generate a policy that allows every operation the application executes. The created policy functions as a base that can be refined. +.It Fl u +Do not perform aliasing on system call names. .It Fl i Inherits the policy of the first executed binary to all children. .It Fl t 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(); diff --git a/bin/systrace/systrace.h b/bin/systrace/systrace.h index 18d25cbad58..d8392f5807d 100644 --- a/bin/systrace/systrace.h +++ b/bin/systrace/systrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.h,v 1.5 2002/06/07 18:05:20 provos Exp $ */ +/* $OpenBSD: systrace.h,v 1.6 2002/07/09 15:22:27 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -111,10 +111,48 @@ struct filterq *systrace_policyflq(struct policy *, char *, char *); int systrace_error_translate(char *); +#define SYSTRACE_MAXALIAS 5 + +struct systrace_alias { + SPLAY_ENTRY(systrace_alias) node; + TAILQ_ENTRY(systrace_alias) next; + + char name[64]; + char emulation[16]; + + char aname[64]; + char aemul[16]; + + struct intercept_translate *arguments[SYSTRACE_MAXALIAS]; + int nargs; + + struct systrace_revalias *reverse; +}; + +int systrace_initalias(void); +struct systrace_alias *systrace_new_alias(char *, char *, char *, char *); +void systrace_switch_alias(char *, char *, char *, char *); +struct systrace_alias *systrace_find_alias(char *, char *); +void systrace_alias_add_trans(struct systrace_alias *, + struct intercept_translate *); + +struct systrace_revalias { + SPLAY_ENTRY(systrace_revalias) node; + + char name[64]; + char emulation[16]; + + TAILQ_HEAD(revaliasq, systrace_alias) revl; +}; + +struct systrace_revalias *systrace_reverse(char *, char *); +struct systrace_revalias *systrace_find_reverse(char *, char *); + short filter_evaluate(struct intercept_tlq *, struct filterq *, int *); short filter_ask(struct intercept_tlq *, struct filterq *, int, char *, char *, char *, short *, int *); void filter_free(struct filter *); +void filter_modifypolicy(int, int, char *, char *, short); int filter_parse_simple(char *, short *, short *); int filter_parse(char *, struct filter **); |