sync with latest systrace in openbsd tree. improved systrace with chroot.

This commit is contained in:
itojun 2002-08-28 03:52:44 +00:00
parent 6e85b03958
commit b6aefbe19f
14 changed files with 291 additions and 112 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: filter.c,v 1.4 2002/08/08 13:24:12 soren Exp $ */
/* $OpenBSD: filter.c,v 1.15 2002/07/19 14:38:57 itojun Exp $ */
/* $NetBSD: filter.c,v 1.5 2002/08/28 03:52:44 itojun Exp $ */
/* $OpenBSD: filter.c,v 1.16 2002/08/08 21:18:20 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -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.4 2002/08/08 13:24:12 soren Exp $");
__RCSID("$NetBSD: filter.c,v 1.5 2002/08/28 03:52:44 itojun Exp $");
#include <sys/param.h>
#include <sys/types.h>
@ -355,8 +355,7 @@ filter_ask(struct intercept_tlq *tls, struct filterq *fls,
*pflags = 0;
if ((policy = systrace_findpolnr(policynr)) == NULL)
errx(1, "%s:%d: no policy %d", __func__, __LINE__,
policynr);
errx(1, "%s:%d: no policy %d", __func__, __LINE__, policynr);
if (!allow)
printf("%s\n", output);

View File

@ -1,5 +1,5 @@
/* $NetBSD: intercept-translate.c,v 1.4 2002/07/30 16:29:30 itojun Exp $ */
/* $OpenBSD: intercept-translate.c,v 1.8 2002/07/20 04:19:53 provos Exp $ */
/* $NetBSD: intercept-translate.c,v 1.5 2002/08/28 03:52:45 itojun Exp $ */
/* $OpenBSD: intercept-translate.c,v 1.9 2002/08/01 20:16:45 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -30,7 +30,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: intercept-translate.c,v 1.4 2002/07/30 16:29:30 itojun Exp $");
__RCSID("$NetBSD: intercept-translate.c,v 1.5 2002/08/28 03:52:45 itojun Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -136,7 +136,7 @@ ic_get_filename(struct intercept_translate *trans, int fd, pid_t pid,
char *name;
int len;
name = intercept_filename(fd, pid, addr, 1);
name = intercept_filename(fd, pid, addr, ICLINK_ALL);
if (name == NULL)
return (-1);
@ -182,7 +182,31 @@ ic_get_linkname(struct intercept_translate *trans, int fd, pid_t pid,
char *name;
int len;
name = intercept_filename(fd, pid, addr, 0);
name = intercept_filename(fd, pid, addr, ICLINK_NONE);
if (name == NULL)
return (-1);
len = strlen(name) + 1;
trans->trans_data = malloc(len);
if (trans->trans_data == NULL)
return (-1);
trans->trans_size = len;
memcpy(trans->trans_data, name, len);
return (0);
}
/* Resolves all symlinks but for the last component */
static int
ic_get_unlinkname(struct intercept_translate *trans, int fd, pid_t pid,
void *addr)
{
char *name;
int len;
name = intercept_filename(fd, pid, addr, ICLINK_NOLAST);
if (name == NULL)
return (-1);
@ -281,6 +305,11 @@ struct intercept_translate ic_translate_linkname = {
ic_get_linkname, ic_print_filename,
};
struct intercept_translate ic_translate_unlinkname = {
"filename",
ic_get_unlinkname, ic_print_filename,
};
struct intercept_translate ic_translate_connect = {
"sockaddr",
ic_get_sockaddr, ic_print_sockaddr,

View File

@ -1,5 +1,5 @@
/* $NetBSD: intercept.c,v 1.4 2002/07/30 16:29:30 itojun Exp $ */
/* $OpenBSD: intercept.c,v 1.20 2002/07/30 16:09:48 itojun Exp $ */
/* $NetBSD: intercept.c,v 1.5 2002/08/28 03:52:45 itojun Exp $ */
/* $OpenBSD: intercept.c,v 1.29 2002/08/28 03:30:27 itojun Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -30,13 +30,14 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: intercept.c,v 1.4 2002/07/30 16:29:30 itojun Exp $");
__RCSID("$NetBSD: intercept.c,v 1.5 2002/08/28 03:52:45 itojun Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/tree.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
@ -111,6 +112,7 @@ SPLAY_PROTOTYPE(pidtree, intercept_pid, next, pidcompare);
SPLAY_GENERATE(pidtree, intercept_pid, next, pidcompare);
extern struct intercept_system intercept;
int ic_abort;
int
intercept_init(void)
@ -488,22 +490,32 @@ intercept_replace(int fd, pid_t pid, struct intercept_replace *repl)
char *
intercept_get_string(int fd, pid_t pid, void *addr)
{
static char name[MAXPATHLEN];
int off = 0, done = 0;
static char name[8192];
int off = 0, done = 0, stride;
stride = 32;
do {
if (intercept.io(fd, pid, INTERCEPT_READ, (char *)addr + off,
&name[off], 4) == -1) {
warn("%s: ioctl", __func__);
return (NULL);
&name[off], stride) == -1) {
/* Did the current system call get interrupted? */
if (errno == EBUSY)
return (NULL);
if (errno != EINVAL || stride == 4) {
warn("%s: ioctl", __func__);
return (NULL);
}
/* Try smaller stride */
stride /= 2;
continue;
}
off += 4;
off += stride;
name[off] = '\0';
if (strlen(name) < off)
done = 1;
} while (!done && off + 5 < sizeof(name));
} while (!done && off + stride + 1 < sizeof(name));
if (!done) {
warnx("%s: string too long", __func__);
@ -521,11 +533,16 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
name = intercept_get_string(fd, pid, addr);
if (name == NULL)
err(1, "%s: getstring", __func__);
goto abort;
if (intercept.getcwd(fd, pid, cwd, sizeof(cwd)) == NULL)
if (name[0] != '/')
err(1, "%s: getcwd", __func__);
if (intercept.getcwd(fd, pid, cwd, sizeof(cwd)) == NULL) {
if (errno == EBUSY)
goto abort;
if (strcmp(name, "/") == 0)
return (name);
err(1, "%s: getcwd", __func__);
}
if (name[0] != '/') {
if (strlcat(cwd, "/", sizeof(cwd)) >= sizeof(cwd))
@ -537,10 +554,22 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
goto error;
}
if (userp) {
if (userp != ICLINK_NONE) {
static char rcwd[2*MAXPATHLEN];
int failed = 0;
/* If realpath fails then the filename does not exist */
if (userp == ICLINK_NOLAST) {
char *file = basename(cwd);
/* Check if the last component has special meaning */
if (strcmp(file, ".") == 0 || strcmp(file, "..") == 0)
userp = ICLINK_ALL;
else
goto nolast;
}
/* If realpath fails then the filename does not exist,
* or we are supposed to not resolve the last component */
if (realpath(cwd, rcwd) == NULL) {
char *dir, *file;
struct stat st;
@ -550,6 +579,7 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
goto out;
}
nolast:
/* Component of path could not be entered */
if (strlcpy(rcwd, cwd, sizeof(rcwd)) >= sizeof(rcwd))
goto error;
@ -563,7 +593,9 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
failed = 1;
goto out;
}
if (strlcat(rcwd, "/", sizeof(rcwd)) >= sizeof(rcwd))
/* If path is not "/" append a "/" */
if (strlen(rcwd) > 1 &&
strlcat(rcwd, "/", sizeof(rcwd)) >= sizeof(rcwd))
goto error;
if (strlcat(rcwd, file, sizeof(rcwd)) >= sizeof(rcwd))
goto error;
@ -571,8 +603,11 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
* At this point, filename has to exist and has to
* be a directory.
*/
if (lstat(rcwd, &st) == -1 || !(st.st_mode & S_IFDIR))
if (lstat(rcwd, &st) == -1)
failed = 1;
else if (userp != ICLINK_NOLAST &&
!(st.st_mode & S_IFDIR))
failed = 1;
}
out:
if (failed)
@ -591,6 +626,10 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
return (name);
abort:
ic_abort = 1;
return (NULL);
error:
errx(1, "%s: filename too long", __func__);
}
@ -610,6 +649,7 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr,
if (!strcmp(name, "execve")) {
struct intercept_pid *icpid;
void *addr;
char *argname;
if ((icpid = intercept_getpid(pid)) == NULL)
err(1, "intercept_getpid");
@ -621,7 +661,11 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr,
free(icpid->newname);
intercept.getarg(0, args, argsize, &addr);
icpid->newname = strdup(intercept_filename(fd, pid, addr, 0));
argname = intercept_filename(fd, pid, addr, 0);
if (argname == NULL)
err(1, "%s:%d: intercept_filename",
__func__, __LINE__);
icpid->newname = strdup(argname);
if (icpid->newname == NULL)
err(1, "%s:%d: strdup", __func__, __LINE__);
@ -635,14 +679,18 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr,
if (sc != NULL) {
struct intercept_translate *tl;
ic_abort = 0;
TAILQ_FOREACH(tl, &sc->tls, next) {
if (intercept_translate(tl, fd, pid, tl->off,
args, argsize) == -1)
break;
}
action = (*sc->cb)(fd, pid, policynr, name, code, emulation,
args, argsize, &sc->tls, sc->cb_arg);
if (!ic_abort)
action = (*sc->cb)(fd, pid, policynr, name, code,
emulation, args, argsize, &sc->tls, sc->cb_arg);
else
action = ICPOLICY_NEVER;
} else if (intercept_gencb != NULL)
action = (*intercept_gencb)(fd, pid, policynr, name, code,
emulation, args, argsize, intercept_gencbarg);
@ -680,10 +728,16 @@ intercept_syscall_result(int fd, pid_t pid, u_int16_t seqnr, int policynr,
icpid->name, intercept_newimagecbarg);
} else if (!strcmp("setuid", name)) {
intercept.getarg(0, args, argsize, (void **)&icpid->uid);
register_t reg;
intercept.getarg(0, args, argsize, (void **)&reg);
icpid->uid = reg;
icpid->flags |= ICFLAGS_UIDKNOWN;
} else if (!strcmp("setgid", name)) {
intercept.getarg(0, args, argsize, (void **)&icpid->gid);
register_t reg;
intercept.getarg(0, args, argsize, (void **)&reg);
icpid->gid = reg;
icpid->flags |= ICFLAGS_GIDKNOWN;
}
out:
@ -745,6 +799,9 @@ intercept_child_info(pid_t opid, pid_t npid)
err(1, "%s:%d: strdup", __func__, __LINE__);
}
/* Process tree */
inpid->ppid = opid;
/* Copy some information */
inpid->flags = ipid->flags;
inpid->uid = ipid->uid;

View File

@ -1,5 +1,5 @@
/* $NetBSD: intercept.h,v 1.3 2002/07/30 16:29:30 itojun Exp $ */
/* $OpenBSD: intercept.h,v 1.9 2002/07/22 04:02:39 provos Exp $ */
/* $NetBSD: intercept.h,v 1.4 2002/08/28 03:52:45 itojun Exp $ */
/* $OpenBSD: intercept.h,v 1.11 2002/08/04 04:15:50 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -67,11 +67,16 @@ struct intercept_system {
#define ICPOLICY_KILL -2
#define ICPOLICY_NEVER 1 /* overloaded with errno values > 1 */
#define ICLINK_NONE 0 /* do not resolve symlinks */
#define ICLINK_ALL 1 /* resolve all symlinks */
#define ICLINK_NOLAST 2 /* do not resolve last component */
#define ICFLAGS_RESULT 1
struct intercept_pid {
SPLAY_ENTRY(intercept_pid) next;
pid_t pid;
pid_t ppid; /* parent pid */
short policynr;
int execve_code;
@ -157,6 +162,7 @@ char *intercept_translate_print(struct intercept_translate *);
extern struct intercept_translate ic_translate_string;
extern struct intercept_translate ic_translate_filename;
extern struct intercept_translate ic_translate_linkname;
extern struct intercept_translate ic_translate_unlinkname;
extern struct intercept_translate ic_translate_connect;
void intercept_freepid(pid_t);

View File

@ -1,5 +1,5 @@
/* $NetBSD: lex.l,v 1.2 2002/07/30 16:29:30 itojun Exp $ */
/* $OpenBSD: lex.l,v 1.8 2002/07/30 05:39:31 itojun Exp $ */
/* $NetBSD: lex.l,v 1.3 2002/08/28 03:52:45 itojun Exp $ */
/* $OpenBSD: lex.l,v 1.9 2002/08/04 04:15:50 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -34,7 +34,7 @@
%{
#include <sys/cdefs.h>
__RCSID("$NetBSD: lex.l,v 1.2 2002/07/30 16:29:30 itojun Exp $");
__RCSID("$NetBSD: lex.l,v 1.3 2002/08/28 03:52:45 itojun Exp $");
#include <sys/types.h>
#include <sys/tree.h>
@ -89,6 +89,7 @@ neq { return NEQ; }
sub { return SUB; }
nsub { return NSUB; }
inpath { return INPATH; }
log { return LOG; }
true { return TRUE; }
"->" { return THEN; }
\( { return LBRACE; }

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd-syscalls.c,v 1.6 2002/07/30 16:29:30 itojun Exp $ */
/* $NetBSD: netbsd-syscalls.c,v 1.7 2002/08/28 03:52:45 itojun Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: netbsd-syscalls.c,v 1.6 2002/07/30 16:29:30 itojun Exp $");
__RCSID("$NetBSD: netbsd-syscalls.c,v 1.7 2002/08/28 03:52:45 itojun Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -99,6 +99,7 @@ __RCSID("$NetBSD: netbsd-syscalls.c,v 1.6 2002/07/30 16:29:30 itojun Exp $");
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include "intercept.h"
@ -363,13 +364,13 @@ nbsd_translate_flags(short flags)
}
static int
nbsd_translate_errno(int errno)
nbsd_translate_errno(int nerrno)
{
return (errno);
return (nerrno);
}
static int
nbsd_answer(int fd, pid_t pid, u_int32_t seqnr, short policy, int errno,
nbsd_answer(int fd, pid_t pid, u_int32_t seqnr, short policy, int nerrno,
short flags)
{
struct systrace_answer ans;
@ -378,7 +379,7 @@ nbsd_answer(int fd, pid_t pid, u_int32_t seqnr, short policy, int errno,
ans.stra_seqnr = seqnr;
ans.stra_policy = nbsd_translate_policy(policy);
ans.stra_flags = nbsd_translate_flags(flags);
ans.stra_error = nbsd_translate_errno(errno);
ans.stra_error = nbsd_translate_errno(nerrno);
if (ioctl(fd, STRIOCANSWER, &ans) == -1)
return (-1);
@ -466,8 +467,9 @@ nbsd_replace(int fd, pid_t pid, struct intercept_replace *repl)
}
ret = ioctl(fd, STRIOCREPLACE, &replace);
if (ret == -1)
if (ret == -1 && errno != EBUSY) {
warn("%s: ioctl", __func__);
}
free(replace.strr_base);
@ -478,6 +480,7 @@ static int
nbsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size)
{
struct systrace_io io;
extern int ic_abort;
memset(&io, 0, sizeof(io));
io.strio_pid = pid;
@ -485,8 +488,11 @@ nbsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size)
io.strio_len = size;
io.strio_offs = addr;
io.strio_op = (op == INTERCEPT_READ ? SYSTR_READ : SYSTR_WRITE);
if (ioctl(fd, STRIOCIO, &io) == -1)
if (ioctl(fd, STRIOCIO, &io) == -1) {
if (errno == EBUSY)
ic_abort = 1;
return (-1);
}
return (0);
}
@ -500,6 +506,9 @@ nbsd_getcwd(int fd, pid_t pid, char *buf, size_t size)
return (NULL);
path = getcwd(buf, size);
if (path == NULL)
nbsd_restcwd(fd);
return (path);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: openbsd-syscalls.c,v 1.2 2002/07/30 16:29:30 itojun Exp $ */
/* $OpenBSD: openbsd-syscalls.c,v 1.10 2002/07/30 09:16:19 itojun Exp $ */
/* $NetBSD: openbsd-syscalls.c,v 1.3 2002/08/28 03:52:46 itojun Exp $ */
/* $OpenBSD: openbsd-syscalls.c,v 1.12 2002/08/28 03:30:27 itojun Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -81,6 +81,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include "intercept.h"
@ -448,8 +449,9 @@ obsd_replace(int fd, pid_t pid, struct intercept_replace *repl)
}
ret = ioctl(fd, STRIOCREPLACE, &replace);
if (ret == -1)
if (ret == -1 && errno != EBUSY) {
warn("%s: ioctl", __func__);
}
free(replace.strr_base);
@ -460,6 +462,7 @@ static int
obsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size)
{
struct systrace_io io;
extern int ic_abort;
memset(&io, 0, sizeof(io));
io.strio_pid = pid;
@ -467,8 +470,11 @@ obsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size)
io.strio_len = size;
io.strio_offs = addr;
io.strio_op = (op == INTERCEPT_READ ? SYSTR_READ : SYSTR_WRITE);
if (ioctl(fd, STRIOCIO, &io) == -1)
if (ioctl(fd, STRIOCIO, &io) == -1) {
if (errno == EBUSY)
ic_abort = 1;
return (-1);
}
return (0);
}
@ -482,6 +488,9 @@ obsd_getcwd(int fd, pid_t pid, char *buf, size_t size)
return (NULL);
path = getcwd(buf, size);
if (path == NULL)
obsd_restcwd(fd);
return (path);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: parse.y,v 1.2 2002/07/30 16:29:31 itojun Exp $ */
/* $OpenBSD: parse.y,v 1.8 2002/07/30 05:37:21 itojun Exp $ */
/* $NetBSD: parse.y,v 1.3 2002/08/28 03:52:46 itojun Exp $ */
/* $OpenBSD: parse.y,v 1.9 2002/08/04 04:15:50 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -32,7 +32,7 @@
*/
%{
#include <sys/cdefs.h>
__RCSID("$NetBSD: parse.y,v 1.2 2002/07/30 16:29:31 itojun Exp $");
__RCSID("$NetBSD: parse.y,v 1.3 2002/08/28 03:52:46 itojun Exp $");
#include <sys/types.h>
@ -66,7 +66,7 @@ extern int myoff;
%}
%token AND OR NOT LBRACE RBRACE LSQBRACE RSQBRACE THEN MATCH PERMIT DENY
%token EQ NEQ TRUE SUB NSUB INPATH
%token EQ NEQ TRUE SUB NSUB INPATH LOG
%token <string> STRING
%token <string> CMDSTRING
%token <number> NUMBER
@ -74,6 +74,7 @@ extern int myoff;
%type <logic> symbol
%type <action> action
%type <number> typeoff
%type <number> logcode
%type <string> errorcode
%union {
int number;
@ -83,10 +84,7 @@ extern int myoff;
}
%%
filter : fullexpression
;
fullexpression : expression THEN action errorcode
fullexpression : expression THEN action errorcode logcode
{
int flags = 0, errorcode = SYSTRACE_EPERM;
@ -110,6 +108,9 @@ fullexpression : expression THEN action errorcode
break;
}
if ($5)
flags |= SYSCALL_LOG;
if ($4 != NULL)
free($4);
@ -135,6 +136,16 @@ errorcode : /* Empty */
}
;
logcode : /* Empty */
{
$$ = 0;
}
| LOG
{
$$ = 1;
}
;
expression : symbol
{
$$ = $1;

View File

@ -1,5 +1,5 @@
/* $NetBSD: policy.c,v 1.2 2002/07/30 16:29:31 itojun Exp $ */
/* $OpenBSD: policy.c,v 1.13 2002/07/19 14:38:58 itojun Exp $ */
/* $NetBSD: policy.c,v 1.3 2002/08/28 03:52:46 itojun Exp $ */
/* $OpenBSD: policy.c,v 1.15 2002/08/07 00:34:17 vincent Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -30,7 +30,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: policy.c,v 1.2 2002/07/30 16:29:31 itojun Exp $");
__RCSID("$NetBSD: policy.c,v 1.3 2002/08/28 03:52:46 itojun Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -52,7 +52,6 @@ __RCSID("$NetBSD: policy.c,v 1.2 2002/07/30 16:29:31 itojun Exp $");
static int psccompare(struct policy_syscall *, struct policy_syscall *);
static int policycompare(struct policy *, struct policy *);
static int polnrcompare(struct policy *, struct policy *);
static void systrace_setupdir(void);
static char *systrace_policyfilename(char *, const char *);
static int systrace_predicatematch(char *);
static int systrace_writepolicy(struct policy *);
@ -104,21 +103,25 @@ static char *groupnames[NGROUPS_MAX];
static int ngroups;
void
systrace_setupdir(void)
systrace_setupdir(char *path)
{
char *home;
struct stat sb;
home = getenv("HOME");
if (path == NULL) {
home = getenv("HOME");
if (home == NULL)
errx(1, "No HOME environment set");
if (home == NULL)
errx(1, "No HOME environment set");
if (strlcpy(policydir, home, sizeof(policydir)) >= sizeof(policydir))
errx(1, "HOME too long");
if (strlcpy(policydir, home, sizeof(policydir)) >= sizeof(policydir))
errx(1, "HOME too long");
if (strlcat(policydir, "/.systrace", sizeof(policydir)) >= sizeof(policydir))
errx(1, "HOME too long");
if (strlcat(policydir, "/.systrace", sizeof(policydir)) >= sizeof(policydir))
errx(1, "HOME too long");
} else if (strlcpy(policydir, path, sizeof(policydir)) >= sizeof(policydir))
errx(1, "policy directory too long");
if (stat(policydir, &sb) != -1) {
if (!(sb.st_mode & S_IFDIR))
@ -128,7 +131,7 @@ systrace_setupdir(void)
}
int
systrace_initpolicy(char *file)
systrace_initpolicy(char *file, char *path)
{
gid_t groups[NGROUPS_MAX];
char gidbuf[10];
@ -156,7 +159,7 @@ systrace_initpolicy(char *file)
}
if (userpolicy)
systrace_setupdir();
systrace_setupdir(path);
if (file != NULL)
return (systrace_readpolicy(file));
@ -487,7 +490,7 @@ systrace_readpolicy(char *filename)
return (res);
error:
fprintf(stderr, "%s:%d: systax error.\n",
fprintf(stderr, "%s:%d: syntax error.\n",
filename, linenumber);
goto out;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: register.c,v 1.2 2002/08/01 08:47:03 itojun Exp $ */
/* $OpenBSD: register.c,v 1.8 2002/07/30 06:07:06 itojun Exp $ */
/* $NetBSD: register.c,v 1.3 2002/08/28 03:52:46 itojun Exp $ */
/* $OpenBSD: register.c,v 1.11 2002/08/05 14:49:27 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -77,12 +77,14 @@ systrace_initcb(void)
alias = systrace_new_alias("netbsd", "__stat13", "netbsd", "fsread");
systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("netbsd", "__lstat13", trans_cb, NULL));
tl = intercept_register_translink("netbsd", "__lstat13", 0);
tl = intercept_register_translation("netbsd", "__lstat13", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("netbsd", "__lstat13", "netbsd", "fsread");
systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("netbsd", "unlink", trans_cb, NULL));
tl = intercept_register_transfn("netbsd", "unlink", 0);
tl = intercept_register_translation("netbsd", "unlink", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("netbsd", "unlink", "netbsd", "fswrite");
systrace_alias_add_trans(alias, tl);
@ -109,7 +111,8 @@ systrace_initcb(void)
intercept_register_translation("netbsd", "fchmod", 0, &fdt);
intercept_register_translation("netbsd", "fchmod", 1, &modeflags);
X(intercept_register_sccb("netbsd", "readlink", trans_cb, NULL));
tl = intercept_register_translink("netbsd", "readlink", 0);
tl = intercept_register_translation("netbsd", "readlink", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("netbsd", "readlink", "netbsd", "fsread");
systrace_alias_add_trans(alias, tl);
@ -139,7 +142,7 @@ systrace_initcb(void)
intercept_register_transfn("netbsd", "__posix_rename", 1);
X(intercept_register_sccb("netbsd", "symlink", trans_cb, NULL));
intercept_register_transstring("netbsd", "symlink", 0);
intercept_register_translink("netbsd", "symlink", 1);
intercept_register_transfn("netbsd", "symlink", 1);
X(intercept_register_sccb("netbsd", "link", trans_cb, NULL));
intercept_register_transfn("netbsd", "link", 0);
intercept_register_transfn("netbsd", "link", 1);
@ -180,12 +183,14 @@ systrace_initcb(void)
systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("native", "lstat", trans_cb, NULL));
tl = intercept_register_translink("native", "lstat", 0);
tl = intercept_register_translation("native", "lstat", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("native", "lstat", "native", "fsread");
systrace_alias_add_trans(alias, tl);
X(intercept_register_sccb("native", "unlink", trans_cb, NULL));
tl = intercept_register_transfn("native", "unlink", 0);
tl = intercept_register_translation("native", "unlink", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("native", "unlink", "native", "fswrite");
systrace_alias_add_trans(alias, tl);
@ -204,7 +209,8 @@ systrace_initcb(void)
intercept_register_translation("native", "fchmod", 0, &fdt);
intercept_register_translation("native", "fchmod", 1, &modeflags);
X(intercept_register_sccb("native", "readlink", trans_cb, NULL));
tl = intercept_register_translink("native", "readlink", 0);
tl = intercept_register_translation("native", "readlink", 0,
&ic_translate_unlinkname);
alias = systrace_new_alias("native", "readlink", "native", "fsread");
systrace_alias_add_trans(alias, tl);
@ -231,7 +237,7 @@ systrace_initcb(void)
intercept_register_transfn("native", "rename", 1);
X(intercept_register_sccb("native", "symlink", trans_cb, NULL));
intercept_register_transstring("native", "symlink", 0);
intercept_register_translink("native", "symlink", 1);
intercept_register_transfn("native", "symlink", 1);
X(intercept_register_sccb("native", "link", trans_cb, NULL));
intercept_register_transfn("native", "link", 0);
intercept_register_transfn("native", "link", 1);

View File

@ -1,5 +1,5 @@
/* $NetBSD: systrace-translate.c,v 1.5 2002/08/02 14:29:34 itojun Exp $ */
/* $OpenBSD: systrace-translate.c,v 1.9 2002/07/30 06:07:06 itojun Exp $ */
/* $NetBSD: systrace-translate.c,v 1.6 2002/08/28 03:52:46 itojun Exp $ */
/* $OpenBSD: systrace-translate.c,v 1.10 2002/08/01 20:50:17 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -209,6 +209,7 @@ get_argv(struct intercept_translate *trans, int fd, pid_t pid, void *addr)
int i, off = 0, len;
extern struct intercept_system intercept;
i = 0;
buf[0] = '\0';
while (1) {
if (intercept.io(fd, pid, INTERCEPT_READ, (char *)addr + off,
@ -228,6 +229,7 @@ get_argv(struct intercept_translate *trans, int fd, pid_t pid, void *addr)
strlcat(buf, p, sizeof(buf));
off += sizeof(char *);
i++;
}
len = strlen(buf) + 1;

View File

@ -1,5 +1,5 @@
.\" $NetBSD: systrace.1,v 1.11 2002/07/31 00:28:02 itojun Exp $
.\" $OpenBSD: systrace.1,v 1.23 2002/07/30 16:27:21 itojun Exp $
.\" $NetBSD: systrace.1,v 1.12 2002/08/28 03:52:46 itojun Exp $
.\" $OpenBSD: systrace.1,v 1.27 2002/08/05 23:27:53 provos Exp $
.\"
.\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
.\" All rights reserved.
@ -40,6 +40,7 @@
.Sh SYNOPSIS
.Nm systrace
.Op Fl aAituU
.Op Fl d Ar policydir
.Op Fl g Ar gui
.Op Fl f Ar file
.Op Fl p Ar pid
@ -85,6 +86,9 @@ Inherits the policy - child processes inherit policy of the parent binary.
Uses text mode to ask for interactive policy generation.
.It Fl U
Ignore user configured policies and use only global system policies.
.It Fl d Ar policydir
Specifies an alternative location for the user's directory from
which policies are loaded and to which changed policies are stored.
.It Fl g Ar gui
Specifies an alternative location for the notification user interface.
.It Fl f Ar file
@ -104,7 +108,7 @@ as
.Ss POLICY
The policy is specified via the following grammar:
.Bd -literal -offset 4
filter = expression "then" action errorcode
filter = expression "then" action errorcode logcode
expression = symbol | "not" expression | "(" expression ")" |
expression "and" expression | expression "or" expression
symbol = string typeoff "match" cmdstring |
@ -114,6 +118,7 @@ symbol = string typeoff "match" cmdstring |
typeoff = /* empty */ | "[" number "]"
action = "permit" | "deny"
errorcode = /* empty */ | "[" string "]"
logcode = /* empty */ | "log"
.Ed
.Pp
The
@ -177,6 +182,15 @@ Evaluates to true if the system call argument is a subpath of
.Va cmdstring .
.El
.Pp
By appending the
.Va log
statement to a rule, a matching system call and its arguments
is logged to
.Xr syslog 3 .
This is useful, for example, to log all invocations of the
.Va execve
system call.
.Pp
Policy entries may contain an appended predicate.
Predicates have the following format:
.Bd -literal -offset 4

View File

@ -1,5 +1,5 @@
/* $NetBSD: systrace.c,v 1.4 2002/07/30 16:29:31 itojun Exp $ */
/* $OpenBSD: systrace.c,v 1.30 2002/07/30 05:52:50 itojun Exp $ */
/* $NetBSD: systrace.c,v 1.5 2002/08/28 03:52:47 itojun Exp $ */
/* $OpenBSD: systrace.c,v 1.32 2002/08/05 23:27:53 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -29,8 +29,6 @@
* (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/cdefs.h>
__RCSID("$NetBSD: systrace.c,v 1.4 2002/07/30 16:29:31 itojun Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -72,7 +70,8 @@ static int requestor_start(char *);
*/
void
make_output(char *output, size_t outlen, const char *binname, pid_t pid,
make_output(char *output, size_t outlen, const char *binname,
pid_t pid, pid_t ppid,
int policynr, const char *policy, int nfilters, const char *emulation,
const char *name, int code, struct intercept_tlq *tls,
struct intercept_replace *repl)
@ -82,8 +81,8 @@ make_output(char *output, size_t outlen, const char *binname, pid_t pid,
int size;
snprintf(output, outlen,
"%s, pid: %d(%d), policy: %s, filters: %d, syscall: %s-%s(%d)",
binname, pid, policynr, policy, nfilters,
"%s, pid: %d(%d)[%d], policy: %s, filters: %d, syscall: %s-%s(%d)",
binname, pid, policynr, ppid, policy, nfilters,
emulation, name, code);
p = output + strlen(output);
@ -91,6 +90,10 @@ make_output(char *output, size_t outlen, const char *binname, pid_t pid,
if (repl != NULL)
intercept_replace_init(repl);
if (tls == NULL)
return;
TAILQ_FOREACH(tl, tls, next) {
if (!tl->trans_valid)
break;
@ -123,6 +126,8 @@ trans_cb(int fd, pid_t pid, int policynr,
struct filterq *pflq = NULL;
const char *binname = NULL;
char output[_POSIX2_LINE_MAX];
pid_t ppid;
int log = 0;
action = ICPOLICY_PERMIT;
@ -136,9 +141,10 @@ trans_cb(int fd, pid_t pid, int policynr,
ipid = intercept_getpid(pid);
ipid->uflags = 0;
binname = ipid->name != NULL ? ipid->name : policy->name;
ppid = ipid->ppid;
/* Required to set up replacements */
make_output(output, sizeof(output), binname, pid, policynr,
make_output(output, sizeof(output), binname, pid, ppid, policynr,
policy->name, policy->nfilters, emulation, name, code,
tls, &repl);
@ -176,14 +182,14 @@ trans_cb(int fd, pid_t pid, int policynr,
if (action != ICPOLICY_ASK)
goto replace;
make_output(output, sizeof(output), binname, pid, policynr,
policy->name, policy->nfilters,
make_output(output, sizeof(output), binname, pid, ppid,
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);
log = 1;
goto out;
}
@ -201,12 +207,20 @@ trans_cb(int fd, pid_t pid, int policynr,
return (ICPOLICY_NEVER);
}
replace:
if (ipid->uflags & SYSCALL_LOG)
log = 1;
if (action < ICPOLICY_NEVER) {
/* If we can not rewrite the arguments, system call fails */
if (intercept_replace(fd, pid, &repl) == -1)
action = ICPOLICY_NEVER;
}
out:
if (log)
syslog(LOG_WARNING, "%s user: %s, prog: %s",
action < ICPOLICY_NEVER ? "permit" : "deny",
username, output);
return (action);
}
@ -219,6 +233,7 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
struct intercept_pid *ipid;
short action = ICPOLICY_PERMIT;
short future;
int len, off, log = 0;
if (policynr == -1)
goto out;
@ -229,14 +244,21 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
ipid = intercept_getpid(pid);
ipid->uflags = 0;
snprintf(output, sizeof(output),
"%s, pid: %d(%d), policy: %s, filters: %d, syscall: %s-%s(%d), args: %d",
ipid->name != NULL ? ipid->name : policy->name, pid, policynr,
policy->name, policy->nfilters, emulation, name, code, argsize);
make_output(output, sizeof(output),
ipid->name != NULL ? ipid->name : policy->name,
pid, ipid->ppid, policynr,
policy->name, policy->nfilters, emulation, name, code,
NULL, NULL);
off = strlen(output);
len = sizeof(output) - off;
if (len > 0)
snprintf(output + off, len, ", args: %d", argsize);
if (policy->flags & POLICY_UNSUPERVISED) {
action = ICPOLICY_NEVER;
syslog(LOG_WARNING, "user: %s, prog: %s", username, output);
log = 1;
goto out;
}
@ -250,9 +272,14 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
err(1, "intercept_detach");
} else if (action == ICPOLICY_KILL) {
kill(pid, SIGKILL);
action = ICPOLICY_NEVER;
return (ICPOLICY_NEVER);
}
out:
if (log)
syslog(LOG_WARNING, "%s user: %s, prog: %s",
action < ICPOLICY_NEVER ? "permit" : "deny",
username, output);
return (action);
}
@ -334,7 +361,7 @@ static void
usage(void)
{
fprintf(stderr,
"Usage: systrace [-aituU] [-g gui] [-f policy] [-p pid] command ...\n");
"Usage: systrace [-aituU] [-d poldir] [-g gui] [-f policy] [-p pid] command ...\n");
exit(1);
}
@ -391,16 +418,20 @@ main(int argc, char **argv)
int i, c;
char **args;
char *filename = NULL;
char *policypath = NULL;
char *guipath = _PATH_XSYSTRACE;
pid_t pidattach = 0;
int usex11 = 1;
int background;
while ((c = getopt(argc, argv, "aAituUg:f:p:")) != -1) {
while ((c = getopt(argc, argv, "aAituUd:g:f:p:")) != -1) {
switch (c) {
case 'a':
automatic = 1;
break;
case 'd':
policypath = optarg;
break;
case 'A':
allow = 1;
break;
@ -448,7 +479,7 @@ main(int argc, char **argv)
/* Local initalization */
systrace_initalias();
systrace_initpolicy(filename);
systrace_initpolicy(filename, policypath);
systrace_initcb();
if ((trfd = intercept_open()) == -1)

View File

@ -1,5 +1,5 @@
/* $NetBSD: systrace.h,v 1.3 2002/08/01 08:47:04 itojun Exp $ */
/* $OpenBSD: systrace.h,v 1.12 2002/07/30 06:07:06 itojun Exp $ */
/* $NetBSD: systrace.h,v 1.4 2002/08/28 03:52:47 itojun Exp $ */
/* $OpenBSD: systrace.h,v 1.14 2002/08/05 23:27:53 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@ -99,8 +99,10 @@ struct policy {
#define PROCESS_INHERIT_POLICY 0x01 /* Process inherits policy */
#define PROCESS_DETACH 0x02 /* Process gets detached */
#define SYSCALL_LOG 0x04 /* Log this system call */
int systrace_initpolicy(char *);
int systrace_initpolicy(char *, char *);
void systrace_setupdir(char *);
void systrace_initcb(void);
struct policy *systrace_newpolicy(const char *, const char *);
int systrace_newpolicynr(int, struct policy *);
@ -168,7 +170,7 @@ char *uid_to_name(uid_t);
char *strrpl(char *, size_t, char *, char *);
void make_output(char *, size_t, const char *, pid_t, int,
void make_output(char *, size_t, const char *, pid_t, pid_t, int,
const char *, int, const char *, const char *, int, struct intercept_tlq *,
struct intercept_replace *);
short trans_cb(int, pid_t, int, const char *, int, const char *, void *,