From a32e34aa2685b87ba3d6e2ae0bbd1388259b24b7 Mon Sep 17 00:00:00 2001 From: Jun-ichiro itojun Hagino Date: Mon, 9 Dec 2002 07:24:57 +0000 Subject: add support for regular expressions and pidname translations. from provos --- bin/systrace/filter.c | 37 +++++++++-- bin/systrace/filter.h | 3 +- bin/systrace/lex.l | 5 +- bin/systrace/parse.y | 35 ++++++++++- bin/systrace/systrace-translate.c | 127 +++++++++++++++++++++++++++++++++++++- bin/systrace/systrace.1 | 8 ++- bin/systrace/systrace.c | 4 +- bin/systrace/systrace.h | 5 +- 8 files changed, 208 insertions(+), 16 deletions(-) diff --git a/bin/systrace/filter.c b/bin/systrace/filter.c index 3401ae1da38..888f094a548 100644 --- a/bin/systrace/filter.c +++ b/bin/systrace/filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.c,v 1.23 2002/12/09 07:22:52 itojun Exp $ */ +/* $OpenBSD: filter.c,v 1.24 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -95,7 +96,7 @@ filter_match(struct intercept_pid *icpid, struct intercept_tlq *tls, TAILQ_FOREACH(tl, tls, next) { if (!tl->trans_valid) - return (0); + continue; if (strcasecmp(tl->name, logic->type)) continue; @@ -366,7 +367,7 @@ filter_parse_simple(char *rule, short *paction, short *pfuture) if (isfuture) *pfuture = *paction; - return (NULL); + return (0); } void @@ -499,7 +500,7 @@ filter_ask(int fd, struct intercept_tlq *tls, struct filterq *fls, line[0] = '\0'; TAILQ_FOREACH(tl, tls, next) { if (!tl->trans_valid) - break; + continue; l = intercept_translate_print(tl); if (l == NULL) continue; @@ -769,6 +770,34 @@ filter_inpath(struct intercept_translate *tl, struct logic *logic) return (1); } +int +filter_regex(struct intercept_translate *tl, struct logic *logic) +{ + regex_t tmpre, *re; + char *line; + int res; + + if ((line = intercept_translate_print(tl)) == NULL) + return (0); + + re = logic->filterarg; + if (re == NULL) { + /* If regex does not compute, we just do not match */ + if (regcomp(&tmpre, logic->filterdata, + REG_EXTENDED | REG_NOSUB) != 0) + return (0); + re = &tmpre; + } + + res = regexec(re, line, 0, NULL, 0); + + /* Clean up temporary memory associated with regex */ + if (re == &tmpre) + regfree(re); + + return (res == 0); +} + int filter_true(struct intercept_translate *tl, struct logic *logic) { diff --git a/bin/systrace/filter.h b/bin/systrace/filter.h index d22500d2cc6..eff0a17e6ae 100644 --- a/bin/systrace/filter.h +++ b/bin/systrace/filter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: filter.h,v 1.1 2002/07/19 14:38:57 itojun Exp $ */ +/* $OpenBSD: filter.h,v 1.2 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos @@ -36,4 +36,5 @@ int filter_negstringmatch(struct intercept_translate *, struct logic *); int filter_substrmatch(struct intercept_translate *, struct logic *); int filter_negsubstrmatch(struct intercept_translate *, struct logic *); int filter_inpath(struct intercept_translate *, struct logic *); +int filter_regex(struct intercept_translate *, struct logic *); int filter_true(struct intercept_translate *, struct logic *); diff --git a/bin/systrace/lex.l b/bin/systrace/lex.l index 1a1cff1e780..a8920da93dd 100644 --- a/bin/systrace/lex.l +++ b/bin/systrace/lex.l @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.l,v 1.11 2002/10/16 15:01:08 itojun Exp $ */ +/* $OpenBSD: lex.l,v 1.12 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos @@ -81,6 +81,7 @@ neq { return NEQ; } sub { return SUB; } nsub { return NSUB; } inpath { return INPATH; } +re { return RE; } log { return LOG; } true { return TRUE; } "->" { return THEN; } @@ -96,7 +97,7 @@ as { return AS; } "!=" { return NEQUAL; } [\$A-Za-z][\.\(\)\/A-Za-z_\-0-9]* { yylval.string = strdup(yytext); return STRING; } [0-9]+ { yylval.number = atoi(yytext); return NUMBER; } -\"[^\"]+\" { char line[1024]; +\"[^\"]*\" { char line[1024]; strlcpy(line, yytext + 1, sizeof(line)); line[strlen(line)-1] = '\0'; yylval.string = strdup(line); diff --git a/bin/systrace/parse.y b/bin/systrace/parse.y index e046a980694..849ffadc8b6 100644 --- a/bin/systrace/parse.y +++ b/bin/systrace/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.12 2002/11/26 03:47:08 itojun Exp $ */ +/* $OpenBSD: parse.y,v 1.13 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos @@ -43,6 +43,7 @@ #include #include #include +#include #include "intercept.h" #include "systrace.h" @@ -67,7 +68,7 @@ extern int iamroot; %token AND OR NOT LBRACE RBRACE LSQBRACE RSQBRACE THEN MATCH PERMIT DENY %token EQ NEQ TRUE SUB NSUB INPATH LOG COMMA IF USER GROUP EQUAL NEQUAL AS -%token COLON +%token COLON RE %token STRING %token CMDSTRING %token NUMBER @@ -352,6 +353,36 @@ symbol : STRING typeoff MATCH CMDSTRING node->filter_match = filter_inpath; $$ = node; +} + | STRING typeoff RE CMDSTRING +{ + struct logic *node; + regex_t *re; + + if ((node = parse_newsymbol($1, $2, $4)) == NULL) + break; + + if ((re = calloc(1, sizeof (regex_t))) == NULL) { + yyerror("calloc"); + break; + } + + /* Precompute regexp here, otherwise we need to compute it + * on the fly which is fairly expensive. + */ + if (!(node->flags & LOGIC_NEEDEXPAND)) { + if (regcomp(re, node->filterdata, + REG_EXTENDED | REG_NOSUB) != 0) { + yyerror("Invalid regular expression: %s", + node->filterdata); + break; + } + node->filterarg = re; + } else + node->filterarg = NULL; + + node->filter_match = filter_regex; + $$ = node; } | TRUE { diff --git a/bin/systrace/systrace-translate.c b/bin/systrace/systrace-translate.c index c2965723fa0..f7863c7aa8c 100644 --- a/bin/systrace/systrace-translate.c +++ b/bin/systrace/systrace-translate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace-translate.c,v 1.13 2002/11/16 14:27:17 itojun Exp $ */ +/* $OpenBSD: systrace-translate.c,v 1.14 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -59,7 +59,8 @@ static int linux_print_oflags(char *, size_t, struct intercept_translate *); static int print_modeflags(char *, size_t, struct intercept_translate *); static int print_number(char *, size_t, struct intercept_translate *); static int print_uname(char *, size_t, struct intercept_translate *); -static int print_uname(char *, size_t, struct intercept_translate *); +static int print_pidname(char *, size_t, struct intercept_translate *); +static int print_signame(char *, size_t, struct intercept_translate *); static int get_argv(struct intercept_translate *, int, pid_t, void *); static int print_argv(char *, size_t, struct intercept_translate *); @@ -255,6 +256,118 @@ print_uname(char *buf, size_t buflen, struct intercept_translate *tl) return (0); } +static int +print_pidname(char *buf, size_t buflen, struct intercept_translate *tl) +{ + struct intercept_pid *icpid; + pid_t pid = (intptr_t)tl->trans_addr; + + icpid = intercept_getpid(pid); + snprintf(buf, buflen, "%s", + icpid->name != NULL ? icpid->name : ""); + + if (icpid->name == NULL) + intercept_freepid(pid); + + return (0); +} + +static int +print_signame(char *buf, size_t buflen, struct intercept_translate *tl) +{ + int sig = (intptr_t)tl->trans_addr; + char *name; + + switch (sig) { + case SIGHUP: + name = "SIGHUP"; + break; + case SIGINT: + name = "SIGINT"; + break; + case SIGQUIT: + name = "SIGQUIT"; + break; + case SIGILL: + name = "SIGILL"; + break; + case SIGABRT: + name = "SIGABRT"; + break; + case SIGFPE: + name = "SIGFPE"; + break; + case SIGKILL: + name = "SIGKILL"; + break; + case SIGBUS: + name = "SIGBUS"; + break; + case SIGSEGV: + name = "SIGSEGV"; + break; + case SIGSYS: + name = "SIGSYS"; + break; + case SIGPIPE: + name = "SIGPIPE"; + break; + case SIGALRM: + name = "SIGALRM"; + break; + case SIGTERM: + name = "SIGTERM"; + break; + case SIGURG: + name = "SIGURG"; + break; + case SIGSTOP: + name = "SIGSTOP"; + break; + case SIGTSTP: + name = "SIGTSTP"; + break; + case SIGCONT: + name = "SIGCONT"; + break; + case SIGCHLD: + name = "SIGCHLD"; + break; + case SIGTTIN: + name = "SIGTTIN"; + break; + case SIGTTOU: + name = "SIGTTOU"; + break; + case SIGIO: + name = "SIGIO"; + break; + case SIGPROF: + name = "SIGPROF"; + break; + case SIGWINCH: + name = "SIGWINCH"; + break; +#ifndef __linux__ + case SIGINFO: + name = "SIGINFO"; + break; +#endif /* !__linux__ */ + case SIGUSR1: + name = "SIGUSR1"; + break; + case SIGUSR2: + name = "SIGUSR2"; + break; + default: + snprintf(buf, buflen, ": %d", sig); + return (0); + } + + snprintf(buf, buflen, "%s", name); + return (0); +} + static int get_argv(struct intercept_translate *trans, int fd, pid_t pid, void *addr) { @@ -355,3 +468,13 @@ struct intercept_translate ic_socktype = { "socktype", NULL, print_socktype, }; + +struct intercept_translate ic_pidname = { + "pidname", + NULL, print_pidname, +}; + +struct intercept_translate ic_signame = { + "signame", + NULL, print_signame, +}; diff --git a/bin/systrace/systrace.1 b/bin/systrace/systrace.1 index 3dc1c55b215..ad90989c189 100644 --- a/bin/systrace/systrace.1 +++ b/bin/systrace/systrace.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: systrace.1,v 1.29 2002/10/31 23:04:09 itojun Exp $ +.\" $OpenBSD: systrace.1,v 1.30 2002/12/09 07:24:56 itojun Exp $ .\" .\" Copyright 2002 Niels Provos .\" All rights reserved. @@ -126,7 +126,8 @@ expression = symbol | "not" expression | "(" expression ")" | symbol = string typeoff "match" cmdstring | string typeoff "eq" cmdstring | string typeoff "neq" cmdstring | string typeoff "sub" cmdstring | string typeoff "nsub" cmdstring | - string typeoff "inpath" cmdstring | "true" + string typeoff "inpath" cmdstring | string typeoff "re" cmdstring | + "true" typeoff = /* empty */ | "[" number "]" action = "permit" | "deny" errorcode = /* empty */ | "[" string "]" @@ -193,6 +194,9 @@ This is the logical negation of .It inpath Evaluates to true if the system call argument is a subpath of .Va cmdstring . +.It re +Evaluates to true if the system call arguments matches +the specified regular expression. .El .Pp By appending the diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c index e8129d4af77..50cf86bc90c 100644 --- a/bin/systrace/systrace.c +++ b/bin/systrace/systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.c,v 1.39 2002/10/28 17:10:10 itojun Exp $ */ +/* $OpenBSD: systrace.c,v 1.40 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -119,7 +119,7 @@ make_output(char *output, size_t outlen, const char *binname, TAILQ_FOREACH(tl, tls, next) { if (!tl->trans_valid) - break; + continue; line = intercept_translate_print(tl); if (line == NULL) continue; diff --git a/bin/systrace/systrace.h b/bin/systrace/systrace.h index 9604b42d6ff..4e4e2705b37 100644 --- a/bin/systrace/systrace.h +++ b/bin/systrace/systrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systrace.h,v 1.19 2002/11/16 14:27:17 itojun Exp $ */ +/* $OpenBSD: systrace.h,v 1.20 2002/12/09 07:24:56 itojun Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -47,6 +47,7 @@ struct logic { void *filterdata; size_t filterlen; int (*filter_match)(struct intercept_translate *, struct logic *); + void *filterarg; }; #define LOGIC_NEEDEXPAND 0x01 @@ -220,6 +221,8 @@ extern struct intercept_translate ic_gidt; extern struct intercept_translate ic_trargv; extern struct intercept_translate ic_sockdom; extern struct intercept_translate ic_socktype; +extern struct intercept_translate ic_pidname; +extern struct intercept_translate ic_signame; extern struct intercept_translate ic_linux_oflags; -- cgit v1.2.3