Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/systrace predicates are part of the grammar now; in non-...
details: https://anonhg.NetBSD.org/src/rev/c38e2838f37c
branches: trunk
changeset: 537928:c38e2838f37c
user: provos <provos%NetBSD.org@localhost>
date: Tue Oct 08 14:49:23 2002 +0000
description:
predicates are part of the grammar now; in non-root case, predicates are
evaluated only once; in root case, predicates and variable expansion are
dynamic.
diffstat:
bin/systrace/filter.c | 158 +++++++++++++++++++++++++++++++--------
bin/systrace/intercept.c | 74 +++++++++++++-----
bin/systrace/intercept.h | 13 ++-
bin/systrace/lex.l | 10 ++-
bin/systrace/netbsd-syscalls.c | 15 +++-
bin/systrace/openbsd-syscalls.c | 13 +++-
bin/systrace/parse.y | 80 ++++++++++++++++++-
bin/systrace/policy.c | 93 +++++------------------
bin/systrace/systrace.c | 57 ++++++++++---
bin/systrace/systrace.h | 25 +++++-
bin/systrace/util.c | 20 +----
bin/systrace/util.h | 8 +-
12 files changed, 385 insertions(+), 181 deletions(-)
diffs (truncated from 1163 to 300 lines):
diff -r 72ce06a06b9c -r c38e2838f37c bin/systrace/filter.c
--- a/bin/systrace/filter.c Tue Oct 08 14:46:24 2002 +0000
+++ b/bin/systrace/filter.c Tue Oct 08 14:49:23 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: filter.c,v 1.8 2002/10/06 03:16:25 provos Exp $ */
+/* $NetBSD: filter.c,v 1.9 2002/10/08 14:49:23 provos Exp $ */
/* $OpenBSD: filter.c,v 1.16 2002/08/08 21:18:20 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos%citi.umich.edu@localhost>
@@ -30,7 +30,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: filter.c,v 1.8 2002/10/06 03:16:25 provos Exp $");
+__RCSID("$NetBSD: filter.c,v 1.9 2002/10/08 14:49:23 provos Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -53,33 +53,38 @@
extern int noalias;
extern int connected;
extern char cwd[];
+extern char home[];
+extern char username[];
static void logic_free(struct logic *);
-static int filter_match(struct intercept_tlq *, struct logic *);
+static int filter_match(struct intercept_pid *, struct intercept_tlq *,
+ struct logic *);
static void filter_review(struct filterq *);
static void filter_templates(const char *);
static int filter_template(int, struct policy *, int);
+static int filter_quickpredicate(struct filter *);
static void filter_policyrecord(struct policy *, struct filter *, const char *,
const char *, char *);
static void filter_replace(char *, size_t, char *, char *);
static int
-filter_match(struct intercept_tlq *tls, struct logic *logic)
+filter_match(struct intercept_pid *icpid, struct intercept_tlq *tls,
+ struct logic *logic)
{
struct intercept_translate *tl;
- int off = 0;
+ int off = 0, res;
switch (logic->op) {
case LOGIC_NOT:
- return (!filter_match(tls, logic->left));
+ return (!filter_match(icpid, tls, logic->left));
case LOGIC_OR:
- if (filter_match(tls, logic->left))
+ if (filter_match(icpid, tls, logic->left))
return (1);
- return (filter_match(tls, logic->right));
+ return (filter_match(icpid, tls, logic->right));
case LOGIC_AND:
- if (!filter_match(tls, logic->left))
+ if (!filter_match(icpid, tls, logic->left))
return (0);
- return (filter_match(tls, logic->right));
+ return (filter_match(icpid, tls, logic->right));
default:
break;
}
@@ -88,6 +93,9 @@
if (logic->type == NULL)
goto match;
+ if (tls == NULL)
+ errx(1, "filter_match has no translators");
+
TAILQ_FOREACH(tl, tls, next) {
if (!tl->trans_valid)
return (0);
@@ -105,11 +113,47 @@
return (0);
match:
- return (logic->filter_match(tl, logic));
+ /* We need to do dynamic expansion on the data */
+ if (logic->filterdata && (logic->flags & LOGIC_NEEDEXPAND)) {
+ char *old = logic->filterdata;
+ size_t oldlen = logic->filterlen;
+
+ logic->filterdata = filter_dynamicexpand(icpid, old);
+ logic->filterlen = strlen(logic->filterdata) + 1;
+
+ res = logic->filter_match(tl, logic);
+
+ logic->filterdata = old;
+ logic->filterlen = oldlen;
+ } else
+ res = logic->filter_match(tl, logic);
+
+ return (res);
+}
+
+/* Evaluate filter predicate */
+
+int
+filter_predicate(struct intercept_pid *icpid, struct predicate *pdc)
+{
+ int negative;
+ int res = 0;
+
+ if (!pdc->p_flags)
+ return (1);
+
+ negative = pdc->p_flags & PREDIC_NEGATIVE;
+ if (pdc->p_flags & PREDIC_UID)
+ res = icpid->uid == pdc->p_uid;
+ else if (pdc->p_flags & PREDIC_GID)
+ res = icpid->uid == pdc->p_uid;
+
+ return (negative ? !res : res);
}
short
-filter_evaluate(struct intercept_tlq *tls, struct filterq *fls, int *pflags)
+filter_evaluate(struct intercept_tlq *tls, struct filterq *fls,
+ struct intercept_pid *icpid)
{
struct filter *filter, *last = NULL;
short action, laction = 0;
@@ -117,7 +161,8 @@
TAILQ_FOREACH(filter, fls, next) {
action = filter->match_action;
- if (filter_match(tls, filter->logicroot)) {
+ if (filter_predicate(icpid, &filter->match_predicate) &&
+ filter_match(icpid, tls, filter->logicroot)) {
/* Profile feedback optimization */
filter->match_count++;
if (last != NULL && last->match_action == action &&
@@ -128,7 +173,7 @@
if (action == ICPOLICY_NEVER)
action = filter->match_error;
- *pflags = filter->match_flags;
+ icpid->uflags = filter->match_flags;
return (action);
}
@@ -351,6 +396,28 @@
}
}
+/* In non-root case, evaluate predicates early */
+
+static int
+filter_quickpredicate(struct filter *filter)
+{
+ struct predicate *pdc;
+ struct intercept_pid icpid;
+
+ pdc = &filter->match_predicate;
+ if (!pdc->p_flags)
+ return (1);
+
+ intercept_setpid(&icpid);
+
+ if (!filter_predicate(&icpid, pdc))
+ return (0);
+
+ memset(pdc, 0, sizeof(filter->match_predicate));
+
+ return (1);
+}
+
int
filter_prepolicy(int fd, struct policy *policy)
{
@@ -358,6 +425,7 @@
struct filter *filter, *parsed;
struct filterq *fls;
short action, future;
+ extern int iamroot;
/* Commit all matching pre-filters */
for (filter = TAILQ_FIRST(&policy->prefilters);
@@ -376,9 +444,11 @@
__func__, __LINE__, filter->rule);
if (future == ICPOLICY_ASK) {
- fls = systrace_policyflq(policy, policy->emulation,
- filter->name);
- TAILQ_INSERT_TAIL(fls, parsed, next);
+ if (iamroot || filter_quickpredicate(parsed)) {
+ fls = systrace_policyflq(policy,
+ policy->emulation, filter->name);
+ TAILQ_INSERT_TAIL(fls, parsed, next);
+ }
} else {
filter_modifypolicy(fd, policy->policynr,
policy->emulation, filter->name, future);
@@ -398,7 +468,7 @@
short
filter_ask(int fd, struct intercept_tlq *tls, struct filterq *fls,
int policynr, const char *emulation, const char *name,
- char *output, short *pfuture, int *pflags)
+ char *output, short *pfuture, struct intercept_pid *icpid)
{
char line[2*MAXPATHLEN], *p;
struct filter *filter;
@@ -407,7 +477,7 @@
int first = 1;
*pfuture = ICPOLICY_ASK;
- *pflags = 0;
+ icpid->uflags = 0;
if ((policy = systrace_findpolnr(policynr)) == NULL)
errx(1, "%s:%d: no policy %d", __func__, __LINE__, policynr);
@@ -505,10 +575,10 @@
continue;
}
- if (fls == NULL)
+ if (fls != NULL)
+ action = filter_evaluate(tls, fls, icpid);
+ else
action = ICPOLICY_PERMIT;
- else
- action = filter_evaluate(tls, fls, pflags);
if (action == ICPOLICY_ASK) {
printf("Filter unmatched.\n");
continue;
@@ -532,7 +602,7 @@
continue;
TAILQ_INSERT_TAIL(fls, filter, next);
- action = filter_evaluate(tls, fls, pflags);
+ action = filter_evaluate(tls, fls, icpid);
if (action == ICPOLICY_ASK) {
TAILQ_REMOVE(fls, filter, next);
printf("Filter unmatched. Freeing it\n");
@@ -563,23 +633,45 @@
filter_expand(char *data)
{
static char expand[2*MAXPATHLEN];
- char *what;
- if (data != NULL)
- strlcpy(expand, data, sizeof(expand));
+ strlcpy(expand, data, sizeof(expand));
- what = getenv("HOME");
- if (what != NULL)
- filter_replace(expand, sizeof(expand), "$HOME", what);
- what = getenv("USER");
- if (what != NULL)
- filter_replace(expand, sizeof(expand), "$USER", what);
-
+ filter_replace(expand, sizeof(expand), "$HOME", home);
+ filter_replace(expand, sizeof(expand), "$USER", username);
filter_replace(expand, sizeof(expand), "$CWD", cwd);
return (expand);
}
+char *
+filter_dynamicexpand(struct intercept_pid *icpid, char *data)
+{
+ static char expand[2*MAXPATHLEN];
+
+ strlcpy(expand, data, sizeof(expand));
+
+ filter_replace(expand, sizeof(expand), "$HOME", icpid->home);
+ filter_replace(expand, sizeof(expand), "$USER", icpid->username);
+ filter_replace(expand, sizeof(expand), "$CWD", icpid->cwd);
+
+ return (expand);
+}
+
+/* Checks if the string needs expansion */
+
+int
+filter_needexpand(char *data)
+{
+ if (strstr(data, "$HOME") != NULL)
+ return (1);
+ if (strstr(data, "$USER") != NULL)
+ return (1);
+ if (strstr(data, "$CWD") != NULL)
+ return (1);
+
+ return (0);
+}
+
int
filter_fnmatch(struct intercept_translate *tl, struct logic *logic)
{
diff -r 72ce06a06b9c -r c38e2838f37c bin/systrace/intercept.c
--- a/bin/systrace/intercept.c Tue Oct 08 14:46:24 2002 +0000
+++ b/bin/systrace/intercept.c Tue Oct 08 14:49:23 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intercept.c,v 1.6 2002/09/17 04:54:36 itojun Exp $ */
+/* $NetBSD: intercept.c,v 1.7 2002/10/08 14:49:23 provos Exp $ */
/* $OpenBSD: intercept.c,v 1.29 2002/08/28 03:30:27 itojun Exp $ */
Home |
Main Index |
Thread Index |
Old Index