Sync with OpenBSD systrace 1.6d.
XXX: Some of the compat-linux systrace is disabled. From elad.
This commit is contained in:
parent
ba06ad7411
commit
ddbf1b0dd9
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: filter.c,v 1.31 2005/08/24 19:09:03 elad Exp $ */
|
/* $NetBSD: filter.c,v 1.32 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: filter.c,v 1.16 2002/08/08 21:18:20 provos Exp $ */
|
/* $OpenBSD: filter.c,v 1.16 2002/08/08 21:18:20 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: filter.c,v 1.31 2005/08/24 19:09:03 elad Exp $");
|
__RCSID("$NetBSD: filter.c,v 1.32 2006/12/10 01:22:02 christos Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -400,6 +400,10 @@ filter_modifypolicy(int fd, int policynr, const char *emulation,
|
||||||
{
|
{
|
||||||
struct systrace_revalias *reverse = NULL;
|
struct systrace_revalias *reverse = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we are dealing with a system call that really
|
||||||
|
* is an alias for something else.
|
||||||
|
*/
|
||||||
if (!noalias)
|
if (!noalias)
|
||||||
reverse = systrace_find_reverse(emulation, name);
|
reverse = systrace_find_reverse(emulation, name);
|
||||||
if (reverse == NULL) {
|
if (reverse == NULL) {
|
||||||
|
@ -444,6 +448,11 @@ filter_quickpredicate(struct filter *filter)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Processes the filters for a policy that have not been applied yet.
|
||||||
|
* Pre-filters get installed when reading a policy. This function
|
||||||
|
* installs a fast-path in the kernel.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
filter_prepolicy(int fd, struct policy *policy)
|
filter_prepolicy(int fd, struct policy *policy)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: intercept.c,v 1.26 2005/12/31 12:33:41 elad Exp $ */
|
/* $NetBSD: intercept.c,v 1.27 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: intercept.c,v 1.29 2002/08/28 03:30:27 itojun Exp $ */
|
/* $OpenBSD: intercept.c,v 1.29 2002/08/28 03:30:27 itojun Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: intercept.c,v 1.26 2005/12/31 12:33:41 elad Exp $");
|
__RCSID("$NetBSD: intercept.c,v 1.27 2006/12/10 01:22:02 christos Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -555,6 +555,9 @@ intercept_get_string(int fd, pid_t pid, void *addr)
|
||||||
static char name[8192];
|
static char name[8192];
|
||||||
int off = 0, done = 0, stride;
|
int off = 0, done = 0, stride;
|
||||||
|
|
||||||
|
if (addr == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
stride = 32;
|
stride = 32;
|
||||||
do {
|
do {
|
||||||
if (intercept.io(fd, pid, INTERCEPT_READ, (char *)addr + off,
|
if (intercept.io(fd, pid, INTERCEPT_READ, (char *)addr + off,
|
||||||
|
@ -642,7 +645,6 @@ normalize_filename(int fd, pid_t pid, char *name, int userp)
|
||||||
havecwd = 1;
|
havecwd = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need concatenated path for simplifypath */
|
|
||||||
if (havecwd && name[0] != '/') {
|
if (havecwd && name[0] != '/') {
|
||||||
if (strlcat(cwd, "/", sizeof(cwd)) >= sizeof(cwd))
|
if (strlcat(cwd, "/", sizeof(cwd)) >= sizeof(cwd))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -707,7 +709,7 @@ normalize_filename(int fd, pid_t pid, char *name, int userp)
|
||||||
*/
|
*/
|
||||||
if (userp != ICLINK_NOLAST) {
|
if (userp != ICLINK_NOLAST) {
|
||||||
if (lstat(rcwd, &st) == -1 ||
|
if (lstat(rcwd, &st) == -1 ||
|
||||||
!(st.st_mode & S_IFDIR))
|
!S_ISDIR(st.st_mode))
|
||||||
failed = 1;
|
failed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -891,6 +893,12 @@ intercept_assignpolicy(int fd, pid_t pid, int policynr)
|
||||||
return (intercept.assignpolicy(fd, pid, policynr));
|
return (intercept.assignpolicy(fd, pid, policynr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
intercept_modifypolicy_nr(int fd, int policynr, int code, short policy)
|
||||||
|
{
|
||||||
|
return (intercept.policy(fd, policynr, code, policy));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
intercept_modifypolicy(int fd, int policynr, const char *emulation,
|
intercept_modifypolicy(int fd, int policynr, const char *emulation,
|
||||||
const char *name, short policy)
|
const char *name, short policy)
|
||||||
|
@ -964,13 +972,28 @@ intercept_ugid(struct intercept_pid *icpid, uid_t uid, gid_t gid)
|
||||||
icpid->gid = gid;
|
icpid->gid = gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the number of a system call
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
intercept_getsyscallnumber(const char *emulation, const char *name)
|
||||||
|
{
|
||||||
|
int nr = intercept.getsyscallnumber(emulation, name);
|
||||||
|
|
||||||
|
if (nr >= INTERCEPT_MAXSYSCALLNR)
|
||||||
|
err(1, "%s: system call number too high: %d", __func__, nr);
|
||||||
|
|
||||||
|
return (nr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checks if the given emulation has a certain system call.
|
* Checks if the given emulation has a certain system call.
|
||||||
* This is a very slow function.
|
* This is a very slow function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
intercept_isvalidsystemcall(char *emulation, char *name)
|
intercept_isvalidsystemcall(const char *emulation, const char *name)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: intercept.h,v 1.19 2006/04/16 05:19:02 provos Exp $ */
|
/* $NetBSD: intercept.h,v 1.20 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: intercept.h,v 1.11 2002/08/04 04:15:50 provos Exp $ */
|
/* $OpenBSD: intercept.h,v 1.11 2002/08/04 04:15:50 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -111,6 +111,7 @@ struct intercept_pid {
|
||||||
struct elevate *elevate; /* privilege elevation request */
|
struct elevate *elevate; /* privilege elevation request */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define INTERCEPT_MAXSYSCALLNR 512
|
||||||
#define INTERCEPT_MAXSYSCALLARGS 10
|
#define INTERCEPT_MAXSYSCALLARGS 10
|
||||||
|
|
||||||
struct intercept_translate {
|
struct intercept_translate {
|
||||||
|
@ -126,6 +127,7 @@ struct intercept_translate {
|
||||||
size_t trans_size;
|
size_t trans_size;
|
||||||
char *trans_print;
|
char *trans_print;
|
||||||
u_int trans_flags;
|
u_int trans_flags;
|
||||||
|
void *user;
|
||||||
TAILQ_ENTRY(intercept_translate) next;
|
TAILQ_ENTRY(intercept_translate) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,6 +151,7 @@ int intercept_read(int);
|
||||||
int intercept_newpolicy(int);
|
int intercept_newpolicy(int);
|
||||||
int intercept_assignpolicy(int, pid_t, int);
|
int intercept_assignpolicy(int, pid_t, int);
|
||||||
int intercept_modifypolicy(int, int, const char *, const char *, short);
|
int intercept_modifypolicy(int, int, const char *, const char *, short);
|
||||||
|
int intercept_modifypolicy_nr(int, int, int, short);
|
||||||
void intercept_child_info(pid_t, pid_t);
|
void intercept_child_info(pid_t, pid_t);
|
||||||
void intercept_policy_free(int);
|
void intercept_policy_free(int);
|
||||||
|
|
||||||
|
@ -197,12 +200,13 @@ void intercept_syscall(int, pid_t, u_int16_t, int, const char *, int,
|
||||||
const char *, void *, int);
|
const char *, void *, int);
|
||||||
void intercept_syscall_result(int, pid_t, u_int16_t, int, const char *, int,
|
void intercept_syscall_result(int, pid_t, u_int16_t, int, const char *, int,
|
||||||
const char *, void *, int, int, void *);
|
const char *, void *, int, int, void *);
|
||||||
void intercept_ugid(struct intercept_pid *, uid_t, gid_t);
|
|
||||||
void intercept_setpid(struct intercept_pid *, uid_t, gid_t);
|
|
||||||
void intercept_newimage(int, pid_t, int, const char *, char *,
|
void intercept_newimage(int, pid_t, int, const char *, char *,
|
||||||
struct intercept_pid *);
|
struct intercept_pid *);
|
||||||
|
void intercept_ugid(struct intercept_pid *, uid_t, gid_t);
|
||||||
|
void intercept_setpid(struct intercept_pid *, uid_t, gid_t);
|
||||||
|
|
||||||
int intercept_isvalidsystemcall(char *, char *);
|
int intercept_getsyscallnumber(const char *, const char *);
|
||||||
|
int intercept_isvalidsystemcall(const char *, const char *);
|
||||||
|
|
||||||
char *intercept_realpath(const char *, char *);
|
char *intercept_realpath(const char *, char *);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: netbsd-syscalls.c,v 1.19 2005/06/27 17:11:20 elad Exp $ */
|
/* $NetBSD: netbsd-syscalls.c,v 1.20 2006/12/10 01:22:02 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: netbsd-syscalls.c,v 1.19 2005/06/27 17:11:20 elad Exp $");
|
__RCSID("$NetBSD: netbsd-syscalls.c,v 1.20 2006/12/10 01:22:02 christos Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -466,6 +466,8 @@ nbsd_replace(int fd, pid_t pid, u_int16_t seqnr,
|
||||||
size_t len, off;
|
size_t len, off;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
|
memset(&replace, 0, sizeof(replace));
|
||||||
|
|
||||||
for (i = 0, len = 0; i < repl->num; i++) {
|
for (i = 0, len = 0; i < repl->num; i++) {
|
||||||
len += repl->len[i];
|
len += repl->len[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: openbsd-syscalls.c,v 1.9 2003/08/25 09:12:45 cb Exp $ */
|
/* $NetBSD: openbsd-syscalls.c,v 1.10 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: openbsd-syscalls.c,v 1.12 2002/08/28 03:30:27 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>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -436,6 +436,8 @@ obsd_replace(int fd, pid_t pid, u_int16_t seqnr,
|
||||||
size_t len, off;
|
size_t len, off;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
|
memset(&replace, 0, sizeof(replace));
|
||||||
|
|
||||||
for (i = 0, len = 0; i < repl->num; i++) {
|
for (i = 0, len = 0; i < repl->num; i++) {
|
||||||
len += repl->len[i];
|
len += repl->len[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: policy.c,v 1.21 2006/03/18 00:35:02 peter Exp $ */
|
/* $NetBSD: policy.c,v 1.22 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: policy.c,v 1.15 2002/08/07 00:34:17 vincent Exp $ */
|
/* $OpenBSD: policy.c,v 1.15 2002/08/07 00:34:17 vincent Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: policy.c,v 1.21 2006/03/18 00:35:02 peter Exp $");
|
__RCSID("$NetBSD: policy.c,v 1.22 2006/12/10 01:22:02 christos Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -46,6 +46,7 @@ __RCSID("$NetBSD: policy.c,v 1.21 2006/03/18 00:35:02 peter Exp $");
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include "intercept.h"
|
#include "intercept.h"
|
||||||
#include "systrace.h"
|
#include "systrace.h"
|
||||||
|
@ -132,7 +133,7 @@ systrace_setupdir(char *path)
|
||||||
|
|
||||||
|
|
||||||
if (stat(policydir, &sb) != -1) {
|
if (stat(policydir, &sb) != -1) {
|
||||||
if (!(sb.st_mode & S_IFDIR))
|
if (!S_ISDIR(sb.st_mode))
|
||||||
errx(1, "Not a directory: \"%s\"", policydir);
|
errx(1, "Not a directory: \"%s\"", policydir);
|
||||||
} else if (mkdir(policydir, 0700) == -1)
|
} else if (mkdir(policydir, 0700) == -1)
|
||||||
err(1, "mkdir(%s)", policydir);
|
err(1, "mkdir(%s)", policydir);
|
||||||
|
@ -150,11 +151,39 @@ systrace_initpolicy(char *file, char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file != NULL)
|
if (file != NULL)
|
||||||
return (systrace_readpolicy(file));
|
return (systrace_readpolicy(file) != NULL ? 0 : -1);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct policy *
|
||||||
|
systrace_findpolicy_wildcard(const char *name)
|
||||||
|
{
|
||||||
|
struct policy tmp, *res;
|
||||||
|
static char path[MAXPATHLEN], lookup[MAXPATHLEN];
|
||||||
|
|
||||||
|
if (strlcpy(path, name, sizeof(path)) >= sizeof(path))
|
||||||
|
errx(1, "%s: path name overflow", __func__);
|
||||||
|
|
||||||
|
strlcpy(lookup, "*/", sizeof(lookup));
|
||||||
|
strlcat(lookup, basename(path), sizeof(lookup));
|
||||||
|
|
||||||
|
tmp.name = lookup;
|
||||||
|
res = SPLAY_FIND(policytree, &policyroot, &tmp);
|
||||||
|
if (res == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* we found the wildcarded policy; now remove it and bind it */
|
||||||
|
SPLAY_REMOVE(policytree, &policyroot, res);
|
||||||
|
|
||||||
|
free(__UNCONST(res->name));
|
||||||
|
if ((res->name = strdup(name)) == NULL)
|
||||||
|
err(1, "%s: strdup", __func__);
|
||||||
|
|
||||||
|
SPLAY_INSERT(policytree, &policyroot, res);
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
struct policy *
|
struct policy *
|
||||||
systrace_findpolicy(const char *name)
|
systrace_findpolicy(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -195,10 +224,14 @@ struct policy *
|
||||||
systrace_newpolicy(const char *emulation, const char *name)
|
systrace_newpolicy(const char *emulation, const char *name)
|
||||||
{
|
{
|
||||||
struct policy *tmp;
|
struct policy *tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
if ((tmp = systrace_findpolicy(name)) != NULL)
|
if ((tmp = systrace_findpolicy(name)) != NULL)
|
||||||
return (tmp);
|
return (tmp);
|
||||||
|
|
||||||
|
if ((tmp = systrace_findpolicy_wildcard(name)) != NULL)
|
||||||
|
return (tmp);
|
||||||
|
|
||||||
tmp = calloc(1, sizeof(struct policy));
|
tmp = calloc(1, sizeof(struct policy));
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -215,20 +248,23 @@ systrace_newpolicy(const char *emulation, const char *name)
|
||||||
TAILQ_INIT(&tmp->filters);
|
TAILQ_INIT(&tmp->filters);
|
||||||
TAILQ_INIT(&tmp->prefilters);
|
TAILQ_INIT(&tmp->prefilters);
|
||||||
|
|
||||||
|
/* Set the default policy to ask */
|
||||||
|
for (i = 0; i < INTERCEPT_MAXSYSCALLNR; i++)
|
||||||
|
tmp->kerneltable[i] = ICPOLICY_ASK;
|
||||||
|
|
||||||
return (tmp);
|
return (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systrace_freepolicy(struct policy *policy)
|
systrace_cleanpolicy(struct policy *policy)
|
||||||
{
|
{
|
||||||
struct filter *filter;
|
struct filter *filter;
|
||||||
struct policy_syscall *pflq;
|
struct policy_syscall *pflq;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (policy->flags & POLICY_CHANGED) {
|
/* Set the default policy to ask */
|
||||||
if (systrace_writepolicy(policy) == -1)
|
for (i = 0; i < INTERCEPT_MAXSYSCALLNR; i++)
|
||||||
fprintf(stderr, "Failed to write policy for %s\n",
|
policy->kerneltable[i] = ICPOLICY_ASK;
|
||||||
policy->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((filter = TAILQ_FIRST(&policy->prefilters)) != NULL) {
|
while ((filter = TAILQ_FIRST(&policy->prefilters)) != NULL) {
|
||||||
TAILQ_REMOVE(&policy->prefilters, filter, policy_next);
|
TAILQ_REMOVE(&policy->prefilters, filter, policy_next);
|
||||||
|
@ -250,6 +286,18 @@ systrace_freepolicy(struct policy *policy)
|
||||||
|
|
||||||
free(pflq);
|
free(pflq);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
systrace_freepolicy(struct policy *policy)
|
||||||
|
{
|
||||||
|
if (policy->flags & POLICY_CHANGED) {
|
||||||
|
if (systrace_writepolicy(policy) == -1)
|
||||||
|
fprintf(stderr, "Failed to write policy for %s\n",
|
||||||
|
policy->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
systrace_cleanpolicy(policy);
|
||||||
|
|
||||||
SPLAY_REMOVE(policytree, &policyroot, policy);
|
SPLAY_REMOVE(policytree, &policyroot, policy);
|
||||||
if (policy->policynr != -1)
|
if (policy->policynr != -1)
|
||||||
|
@ -289,7 +337,7 @@ int
|
||||||
systrace_modifypolicy(int fd, int policynr, const char *name, short action)
|
systrace_modifypolicy(int fd, int policynr, const char *name, short action)
|
||||||
{
|
{
|
||||||
struct policy *policy;
|
struct policy *policy;
|
||||||
int res;
|
int res, nr;
|
||||||
|
|
||||||
if ((policy = systrace_findpolnr(policynr)) == NULL)
|
if ((policy = systrace_findpolnr(policynr)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -297,20 +345,29 @@ systrace_modifypolicy(int fd, int policynr, const char *name, short action)
|
||||||
res = intercept_modifypolicy(fd, policynr, policy->emulation,
|
res = intercept_modifypolicy(fd, policynr, policy->emulation,
|
||||||
name, action);
|
name, action);
|
||||||
|
|
||||||
|
/* Remember the kernel policy */
|
||||||
|
if (res != -1 &&
|
||||||
|
(nr = intercept_getsyscallnumber(policy->emulation, name)) != -1)
|
||||||
|
policy->kerneltable[nr] = action;
|
||||||
|
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Converts an executable name into the corresponding filename that contains
|
||||||
|
* the policy.
|
||||||
|
*/
|
||||||
char *
|
char *
|
||||||
systrace_policyfilename(const char *dirname, const char *name)
|
systrace_policyfilename(const char *pdirname, const char *name)
|
||||||
{
|
{
|
||||||
static char file[2*MAXPATHLEN];
|
static char file[2*MAXPATHLEN];
|
||||||
const char *p;
|
const char *p;
|
||||||
int i, plen;
|
int i, plen;
|
||||||
|
|
||||||
if (strlen(name) + strlen(dirname) + 1 >= sizeof(file))
|
if (strlen(name) + strlen(pdirname) + 1 >= sizeof(file))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
strlcpy(file, dirname, sizeof(file));
|
strlcpy(file, pdirname, sizeof(file));
|
||||||
i = strlen(file);
|
i = strlen(file);
|
||||||
file[i++] = '/';
|
file[i++] = '/';
|
||||||
plen = i;
|
plen = i;
|
||||||
|
@ -331,7 +388,7 @@ systrace_policyfilename(const char *dirname, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
systrace_getpolicyfilename(const char *name)
|
systrace_getpolicyname(const char *name)
|
||||||
{
|
{
|
||||||
char *file = NULL;
|
char *file = NULL;
|
||||||
|
|
||||||
|
@ -354,10 +411,10 @@ systrace_addpolicy(const char *name)
|
||||||
{
|
{
|
||||||
char *file = NULL;
|
char *file = NULL;
|
||||||
|
|
||||||
if ((file = systrace_getpolicyfilename(name)) == NULL)
|
if ((file = systrace_getpolicyname(name)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
return (systrace_readpolicy(file));
|
return (systrace_readpolicy(file) != NULL ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -387,7 +444,7 @@ systrace_templatedir(void)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Check if template directory exists */
|
/* Check if template directory exists */
|
||||||
if (stat(filename, &sb) != -1 && (sb.st_mode & S_IFDIR))
|
if (stat(filename, &sb) != -1 && S_ISDIR(sb.st_mode))
|
||||||
dir = opendir(filename);
|
dir = opendir(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +452,7 @@ systrace_templatedir(void)
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
strlcpy(filename, POLICY_PATH, sizeof(filename));
|
strlcpy(filename, POLICY_PATH, sizeof(filename));
|
||||||
strlcat(filename, "/templates", sizeof(filename));
|
strlcat(filename, "/templates", sizeof(filename));
|
||||||
if (stat(filename, &sb) != -1 && (sb.st_mode & S_IFDIR))
|
if (stat(filename, &sb) != -1 && S_ISDIR(sb.st_mode))
|
||||||
dir = opendir(filename);
|
dir = opendir(filename);
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -411,7 +468,7 @@ systrace_templatedir(void)
|
||||||
sizeof(filename))
|
sizeof(filename))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (stat(filename, &sb) == -1 || !(sb.st_mode & S_IFREG))
|
if (stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
template = systrace_readtemplate(filename, NULL, NULL);
|
template = systrace_readtemplate(filename, NULL, NULL);
|
||||||
|
@ -426,6 +483,8 @@ systrace_templatedir(void)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
errx(1, "%s: template name too long", __func__);
|
errx(1, "%s: template name too long", __func__);
|
||||||
|
|
||||||
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
struct template *
|
struct template *
|
||||||
|
@ -507,8 +566,9 @@ systrace_readtemplate(char *filename, struct policy *policy,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Removes trailing whitespace and comments from the input line */
|
/*
|
||||||
|
* Removes trailing whitespace and comments from the input line.
|
||||||
|
*/
|
||||||
static char *
|
static char *
|
||||||
systrace_policyline(char *line)
|
systrace_policyline(char *line)
|
||||||
{
|
{
|
||||||
|
@ -594,7 +654,8 @@ systrace_policyprocess(struct policy *policy, char *p)
|
||||||
} else if (filter_parse_simple(rule, &action, &future) == 0)
|
} else if (filter_parse_simple(rule, &action, &future) == 0)
|
||||||
resolved = 1;
|
resolved = 1;
|
||||||
|
|
||||||
/* For now, everything that does not seem to be a valid syscall
|
/*
|
||||||
|
* For now, everything that does not seem to be a valid syscall
|
||||||
* does not get fast kernel policies even though the aliasing
|
* does not get fast kernel policies even though the aliasing
|
||||||
* system supports it.
|
* system supports it.
|
||||||
*/
|
*/
|
||||||
|
@ -628,8 +689,13 @@ systrace_policyprocess(struct policy *policy, char *p)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
/*
|
||||||
systrace_readpolicy(char *filename)
|
* Reads policy from specified file.
|
||||||
|
* If policy exists already, this function appends new statements from the
|
||||||
|
* file to the existing policy.
|
||||||
|
*/
|
||||||
|
struct policy *
|
||||||
|
systrace_readpolicy(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct policy *policy;
|
struct policy *policy;
|
||||||
|
@ -639,7 +705,7 @@ systrace_readpolicy(char *filename)
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
if ((fp = fopen(filename, "r")) == NULL)
|
if ((fp = fopen(filename, "r")) == NULL)
|
||||||
return (-1);
|
return (NULL);
|
||||||
|
|
||||||
policy = NULL;
|
policy = NULL;
|
||||||
while (fgets(line, sizeof(line), fp)) {
|
while (fgets(line, sizeof(line), fp)) {
|
||||||
|
@ -655,6 +721,8 @@ systrace_readpolicy(char *filename)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strncasecmp(p, "Policy: ", 8)) {
|
if (!strncasecmp(p, "Policy: ", 8)) {
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
p += 8;
|
p += 8;
|
||||||
name = strsep(&p, ",");
|
name = strsep(&p, ",");
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
|
@ -667,6 +735,10 @@ systrace_readpolicy(char *filename)
|
||||||
policy = systrace_newpolicy(emulation, name);
|
policy = systrace_newpolicy(emulation, name);
|
||||||
if (policy == NULL)
|
if (policy == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
/* Update access time */
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
TIMEVAL_TO_TIMESPEC(&now, &policy->ts_last);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,13 +758,64 @@ systrace_readpolicy(char *filename)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return (res);
|
return (res == -1 ? NULL : policy);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
fprintf(stderr, "%s:%d: syntax error.\n", filename, linenumber);
|
fprintf(stderr, "%s:%d: syntax error.\n", filename, linenumber);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Appends new policy statements if the policy has been updated by
|
||||||
|
* another process. Assumes that policies are append-only.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* -1 if the policy could not be updated.
|
||||||
|
* 0 if the policy has been updated.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
systrace_updatepolicy(int fd, struct policy *policy)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
struct timespec mtimespec;
|
||||||
|
int i, policynr = policy->policynr;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
if ((file = systrace_getpolicyname(policy->name)) == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (stat(file, &sb) == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
mtimespec = sb.st_mtimespec;
|
||||||
|
|
||||||
|
/* Policy does not need updating */
|
||||||
|
if (timespeccmp(&mtimespec, &policy->ts_last, <=))
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/* Reset the existing policy */
|
||||||
|
for (i = 0; i < INTERCEPT_MAXSYSCALLNR; i++) {
|
||||||
|
if (policy->kerneltable[i] == ICPOLICY_ASK)
|
||||||
|
continue;
|
||||||
|
if (intercept_modifypolicy_nr(fd, policynr, i,
|
||||||
|
ICPOLICY_ASK) == -1)
|
||||||
|
errx(1, "%s: failed to modify policy for %d",
|
||||||
|
__func__, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now clean up all filter structures in this policy */
|
||||||
|
systrace_cleanpolicy(policy);
|
||||||
|
|
||||||
|
/* XXX - This does not deal with Detached and Automatic */
|
||||||
|
if (systrace_readpolicy(file) == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/* Resets the changed flag */
|
||||||
|
filter_prepolicy(fd, policy);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
systrace_writepolicy(struct policy *policy)
|
systrace_writepolicy(struct policy *policy)
|
||||||
{
|
{
|
||||||
|
@ -702,6 +825,7 @@ systrace_writepolicy(struct policy *policy)
|
||||||
char tmpname[2*MAXPATHLEN];
|
char tmpname[2*MAXPATHLEN];
|
||||||
char finalname[2*MAXPATHLEN];
|
char finalname[2*MAXPATHLEN];
|
||||||
struct filter *filter;
|
struct filter *filter;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
if ((p = systrace_policyfilename(policydir, policy->name)) == NULL)
|
if ((p = systrace_policyfilename(policydir, policy->name)) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -741,11 +865,33 @@ systrace_writepolicy(struct policy *policy)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update access time */
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
TIMEVAL_TO_TIMESPEC(&now, &policy->ts_last);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
systrace_dumppolicy(void)
|
systrace_updatepolicies(int fd)
|
||||||
|
{
|
||||||
|
struct policy *policy;
|
||||||
|
|
||||||
|
SPLAY_FOREACH(policy, policytree, &policyroot) {
|
||||||
|
/* Check if the policy has been updated */
|
||||||
|
systrace_updatepolicy(fd, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write policy to disk if it has been changed. We need to
|
||||||
|
* call systrace_updatepolicies() before this, so that we
|
||||||
|
* don't clobber changes.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
systrace_dumppolicies(int fd)
|
||||||
{
|
{
|
||||||
struct policy *policy;
|
struct policy *policy;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: register.c,v 1.19 2006/08/21 01:35:11 christos Exp $ */
|
/* $NetBSD: register.c,v 1.20 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: register.c,v 1.11 2002/08/05 14:49:27 provos Exp $ */
|
/* $OpenBSD: register.c,v 1.11 2002/08/05 14:49:27 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -37,9 +37,13 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "intercept.h"
|
#include "intercept.h"
|
||||||
#include "systrace.h"
|
#include "systrace.h"
|
||||||
|
#ifdef notyet /* XXX we don't have the required headers for this */
|
||||||
|
#include "linux_socketcall.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define X(x) if ((x) == -1) \
|
#define X(x) if ((x) == -1) \
|
||||||
err(1, "%s:%d: intercept failed", __func__, __LINE__)
|
err(1, "%s:%d: intercept failed", __func__, __LINE__)
|
||||||
|
@ -425,7 +429,7 @@ systrace_initcb(void)
|
||||||
intercept_register_translation("native", "seteuid", 0, &ic_uname);
|
intercept_register_translation("native", "seteuid", 0, &ic_uname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !(defined(__NetBSD__) && !defined(HAVE_LINUX_FCNTL_H))
|
#if !(defined(__NetBSD__) || !defined(HAVE_LINUX_FCNTL_H))
|
||||||
/* 5: open [fswrite] */
|
/* 5: open [fswrite] */
|
||||||
X(intercept_register_sccb("linux", "open", trans_cb, NULL));
|
X(intercept_register_sccb("linux", "open", trans_cb, NULL));
|
||||||
tl = intercept_register_translink("linux", "open", 0);
|
tl = intercept_register_translink("linux", "open", 0);
|
||||||
|
@ -459,6 +463,11 @@ systrace_initcb(void)
|
||||||
alias = systrace_new_alias("linux", "access", "linux", "fsread");
|
alias = systrace_new_alias("linux", "access", "linux", "fsread");
|
||||||
systrace_alias_add_trans(alias, tl);
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
|
||||||
|
/* 37: kill */
|
||||||
|
X(intercept_register_sccb("linux", "kill", trans_cb, NULL));
|
||||||
|
intercept_register_translation("linux", "kill", 0, &ic_pidname);
|
||||||
|
intercept_register_translation("linux", "kill", 1, &ic_signame);
|
||||||
|
|
||||||
/* 38: rename */
|
/* 38: rename */
|
||||||
X(intercept_register_sccb("linux", "rename", trans_cb, NULL));
|
X(intercept_register_sccb("linux", "rename", trans_cb, NULL));
|
||||||
intercept_register_translink("linux", "rename", 0);
|
intercept_register_translink("linux", "rename", 0);
|
||||||
|
@ -487,6 +496,20 @@ systrace_initcb(void)
|
||||||
alias = systrace_new_alias("linux", "readlink", "linux", "fsread");
|
alias = systrace_new_alias("linux", "readlink", "linux", "fsread");
|
||||||
systrace_alias_add_trans(alias, tl);
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
|
||||||
|
/* 102: socketcall */
|
||||||
|
X(intercept_register_sccb("linux", "socketcall", trans_cb, NULL));
|
||||||
|
alias = systrace_new_alias("linux", "socketcall", "linux", "_socketcall");
|
||||||
|
tl = intercept_register_translation("linux", "socketcall", 1, &ic_linux_socket_sockdom);
|
||||||
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
tl = intercept_register_translation("linux", "socketcall", 1, &ic_linux_socket_socktype);
|
||||||
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
tl = intercept_register_translation("linux", "socketcall", 1, &ic_linux_connect_sockaddr);
|
||||||
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
tl = intercept_register_translation("linux", "socketcall", 1, &ic_linux_bind_sockaddr);
|
||||||
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
tl = intercept_register_translation("linux", "socketcall", 0, &ic_linux_socketcall_catchall);
|
||||||
|
systrace_alias_add_trans(alias, tl);
|
||||||
|
|
||||||
/* 106: stat [fsread] */
|
/* 106: stat [fsread] */
|
||||||
X(intercept_register_sccb("linux", "stat", trans_cb, NULL));
|
X(intercept_register_sccb("linux", "stat", trans_cb, NULL));
|
||||||
tl = intercept_register_translink("linux", "stat", 0);
|
tl = intercept_register_translink("linux", "stat", 0);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: systrace-error.c,v 1.3 2005/06/24 23:21:09 christos Exp $ */
|
/* $NetBSD: systrace-error.c,v 1.4 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: systrace-error.c,v 1.1 2002/06/04 17:20:04 provos Exp $ */
|
/* $OpenBSD: systrace-error.c,v 1.1 2002/06/04 17:20:04 provos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: systrace-error.c,v 1.3 2005/06/24 23:21:09 christos Exp $");
|
__RCSID("$NetBSD: systrace-error.c,v 1.4 2006/12/10 01:22:02 christos Exp $");
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -40,6 +40,7 @@ __RCSID("$NetBSD: systrace-error.c,v 1.3 2005/06/24 23:21:09 christos Exp $");
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "intercept.h"
|
#include "intercept.h"
|
||||||
#include "systrace.h"
|
#include "systrace.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: systrace-translate.c,v 1.18 2006/11/12 23:29:37 cbiere Exp $ */
|
/* $NetBSD: systrace-translate.c,v 1.19 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: systrace-translate.c,v 1.10 2002/08/01 20:50:17 provos Exp $ */
|
/* $OpenBSD: systrace-translate.c,v 1.10 2002/08/01 20:50:17 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -211,15 +211,15 @@ print_sockdom(char *buf, size_t buflen, struct intercept_translate *tl)
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
what = "AF_INET6";
|
what = "AF_INET6";
|
||||||
break;
|
break;
|
||||||
|
case AF_IPX:
|
||||||
|
what = "AF_IPX";
|
||||||
|
break;
|
||||||
case AF_ISO:
|
case AF_ISO:
|
||||||
what = "AF_ISO";
|
what = "AF_ISO";
|
||||||
break;
|
break;
|
||||||
case AF_NS:
|
case AF_NS:
|
||||||
what = "AF_NS";
|
what = "AF_NS";
|
||||||
break;
|
break;
|
||||||
case AF_IPX:
|
|
||||||
what = "AF_IPX";
|
|
||||||
break;
|
|
||||||
case AF_IMPLINK:
|
case AF_IMPLINK:
|
||||||
what = "AF_IMPLINK";
|
what = "AF_IMPLINK";
|
||||||
break;
|
break;
|
||||||
|
@ -287,12 +287,18 @@ print_pidname(char *buf, size_t buflen, struct intercept_translate *tl)
|
||||||
|
|
||||||
if (pid != 0) {
|
if (pid != 0) {
|
||||||
icpid = intercept_getpid(pid);
|
icpid = intercept_getpid(pid);
|
||||||
strlcpy(buf, icpid->name != NULL ? icpid->name
|
strlcpy(buf, icpid != NULL ? icpid->name : "<unknown>", buflen);
|
||||||
: "<unknown>", buflen);
|
} else if (pid == 0) {
|
||||||
if (icpid->name == NULL)
|
|
||||||
intercept_freepid(pid);
|
|
||||||
} else
|
|
||||||
strlcpy(buf, "<own process group>", buflen);
|
strlcpy(buf, "<own process group>", buflen);
|
||||||
|
} else if (pid == -1) {
|
||||||
|
strlcpy(buf, "<every process: -1>", buflen);
|
||||||
|
} else {
|
||||||
|
/* pid is negative but not -1 - trying to signal pgroup */
|
||||||
|
pid = -pid;
|
||||||
|
icpid = intercept_findpid(pid);
|
||||||
|
strlcpy(buf, "pg:", buflen);
|
||||||
|
strlcat(buf, icpid != NULL ? icpid->name : "unknown", buflen);
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -443,6 +449,32 @@ print_fcntlcmd(char *buf, size_t buflen, struct intercept_translate *tl)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct linux_i386_mmap_arg_struct {
|
||||||
|
unsigned long addr;
|
||||||
|
unsigned long len;
|
||||||
|
unsigned long prot;
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned long fd;
|
||||||
|
unsigned long offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_linux_memprot(struct intercept_translate *trans, int fd, pid_t pid,
|
||||||
|
void *addr)
|
||||||
|
{
|
||||||
|
struct linux_i386_mmap_arg_struct arg;
|
||||||
|
size_t len = sizeof(arg);
|
||||||
|
extern struct intercept_system intercept;
|
||||||
|
|
||||||
|
if (intercept.io(fd, pid, INTERCEPT_READ, addr,
|
||||||
|
(void *)&arg, len) == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
trans->trans_addr = (void *)arg.prot;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_memprot(char *buf, size_t buflen, struct intercept_translate *tl)
|
print_memprot(char *buf, size_t buflen, struct intercept_translate *tl)
|
||||||
{
|
{
|
||||||
|
@ -625,3 +657,8 @@ struct intercept_translate ic_memprot = {
|
||||||
.translate = NULL,
|
.translate = NULL,
|
||||||
.print = print_memprot,
|
.print = print_memprot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct intercept_translate ic_linux_memprot = {
|
||||||
|
"prot",
|
||||||
|
get_linux_memprot, print_memprot,
|
||||||
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $NetBSD: systrace.1,v 1.33 2005/09/03 11:44:45 elad Exp $
|
.\" $NetBSD: systrace.1,v 1.34 2006/12/10 01:22:02 christos Exp $
|
||||||
.\" $OpenBSD: systrace.1,v 1.27 2002/08/05 23:27:53 provos Exp $
|
.\" $OpenBSD: systrace.1,v 1.27 2002/08/05 23:27:53 provos Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
.\" Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm systrace
|
.Nm systrace
|
||||||
.Bk -words
|
.Bk -words
|
||||||
.Op Fl AaCitUu
|
.Op Fl AaCitUuV
|
||||||
.Op Fl c Ar user:group
|
.Op Fl c Ar user:group
|
||||||
.Op Fl d Ar policydir
|
.Op Fl d Ar policydir
|
||||||
.Op Fl f Ar file
|
.Op Fl f Ar file
|
||||||
|
@ -104,12 +104,22 @@ root privilege.
|
||||||
.It Fl d Ar policydir
|
.It Fl d Ar policydir
|
||||||
Specifies an alternative location for the user's directory from
|
Specifies an alternative location for the user's directory from
|
||||||
which policies are loaded and to which changed policies are stored.
|
which policies are loaded and to which changed policies are stored.
|
||||||
|
.It Fl E Ar logfile
|
||||||
|
Logs all policy violations or specifically logged system calls to
|
||||||
|
.Ar logfile .
|
||||||
.It Fl f Ar file
|
.It Fl f Ar file
|
||||||
The policies specified in
|
The policies specified in
|
||||||
.Ar file
|
.Ar file
|
||||||
are added to the policies that
|
are added to the policies that
|
||||||
.Nm
|
.Nm
|
||||||
knows about.
|
knows about.
|
||||||
|
The
|
||||||
|
.Dq dirname
|
||||||
|
inthe policy may contain a
|
||||||
|
.Sq \*
|
||||||
|
to match any possible pathname.
|
||||||
|
The wildcard is removed from the policy database the first time that a
|
||||||
|
filename matches.
|
||||||
.It Fl g Ar gui
|
.It Fl g Ar gui
|
||||||
Specifies an alternative location for the notification user interface.
|
Specifies an alternative location for the notification user interface.
|
||||||
.It Fl i
|
.It Fl i
|
||||||
|
@ -135,6 +145,9 @@ and
|
||||||
.Fn access
|
.Fn access
|
||||||
are translated to
|
are translated to
|
||||||
.Fn fsread .
|
.Fn fsread .
|
||||||
|
.It Fl V
|
||||||
|
Prints the version number of
|
||||||
|
.Nm .
|
||||||
.El
|
.El
|
||||||
.Ss POLICY
|
.Ss POLICY
|
||||||
The policy is specified via the following grammar:
|
The policy is specified via the following grammar:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: systrace.c,v 1.33 2006/05/10 21:53:14 mrg Exp $ */
|
/* $NetBSD: systrace.c,v 1.34 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: systrace.c,v 1.32 2002/08/05 23:27:53 provos Exp $ */
|
/* $OpenBSD: systrace.c,v 1.32 2002/08/05 23:27:53 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -47,6 +47,8 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <event.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "intercept.h"
|
#include "intercept.h"
|
||||||
#include "systrace.h"
|
#include "systrace.h"
|
||||||
|
@ -55,6 +57,8 @@
|
||||||
#define CRADLE_SERVER "cradle_server"
|
#define CRADLE_SERVER "cradle_server"
|
||||||
#define CRADLE_UI "cradle_ui"
|
#define CRADLE_UI "cradle_ui"
|
||||||
|
|
||||||
|
#define VERSION "1.6d (NetBSD)"
|
||||||
|
|
||||||
pid_t trpid;
|
pid_t trpid;
|
||||||
int trfd;
|
int trfd;
|
||||||
int connected = 0; /* Connected to GUI */
|
int connected = 0; /* Connected to GUI */
|
||||||
|
@ -64,15 +68,23 @@ int allow = 0; /* Allow all and generate */
|
||||||
int userpolicy = 1; /* Permit user defined policies */
|
int userpolicy = 1; /* Permit user defined policies */
|
||||||
int noalias = 0; /* Do not do system call aliasing */
|
int noalias = 0; /* Do not do system call aliasing */
|
||||||
int iamroot = 0; /* Set if we are running as root */
|
int iamroot = 0; /* Set if we are running as root */
|
||||||
int cradle = 0; /* Set if we are running in cradle mode */
|
int cradle = 0; /* Set if we are running in cradle mode */
|
||||||
|
int logtofile = 0; /* Log to file instead of syslog */
|
||||||
|
FILE *logfile; /* Default logfile to send to if enabeld */
|
||||||
char cwd[MAXPATHLEN]; /* Current working directory */
|
char cwd[MAXPATHLEN]; /* Current working directory */
|
||||||
char home[MAXPATHLEN]; /* Home directory of user */
|
char home[MAXPATHLEN]; /* Home directory of user */
|
||||||
char username[LOGIN_NAME_MAX]; /* Username: predicate match and expansion */
|
char username[LOGIN_NAME_MAX]; /* Username: predicate match and expansion */
|
||||||
const char *guipath = _PATH_XSYSTRACE; /* Path to GUI executable */
|
const char *guipath = _PATH_XSYSTRACE; /* Path to GUI executable */
|
||||||
char dirpath[MAXPATHLEN];
|
char dirpath[MAXPATHLEN];
|
||||||
|
|
||||||
|
static struct event ev_read;
|
||||||
|
static struct event ev_timeout;
|
||||||
|
|
||||||
static void child_handler(int);
|
static void child_handler(int);
|
||||||
|
static void log_msg(int, const char *, ...);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
static void systrace_read(int, short, void *);
|
||||||
|
static void systrace_timeout(int, short, void *);
|
||||||
|
|
||||||
void
|
void
|
||||||
systrace_parameters(void)
|
systrace_parameters(void)
|
||||||
|
@ -162,7 +174,7 @@ trans_cb(int fd, pid_t pid, int policynr,
|
||||||
const char *binname = NULL;
|
const char *binname = NULL;
|
||||||
char output[_POSIX2_LINE_MAX];
|
char output[_POSIX2_LINE_MAX];
|
||||||
pid_t ppid;
|
pid_t ppid;
|
||||||
int dolog = 0;
|
int done = 0, dolog = 0;
|
||||||
|
|
||||||
ipid = NULL; /* XXXGCC -Wuninitialized [dreamcast] */
|
ipid = NULL; /* XXXGCC -Wuninitialized [dreamcast] */
|
||||||
|
|
||||||
|
@ -181,48 +193,63 @@ trans_cb(int fd, pid_t pid, int policynr,
|
||||||
ppid = ipid->ppid;
|
ppid = ipid->ppid;
|
||||||
|
|
||||||
/* Required to set up replacements */
|
/* Required to set up replacements */
|
||||||
make_output(output, sizeof(output), binname, pid, ppid, policynr,
|
do {
|
||||||
policy->name, policy->nfilters, emulation, name, code,
|
make_output(output, sizeof(output), binname, pid, ppid,
|
||||||
tls, repl);
|
policynr, policy->name, policy->nfilters, emulation,
|
||||||
|
name, code, tls, repl);
|
||||||
|
|
||||||
if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL)
|
/* Fast-path checking */
|
||||||
errx(1, "%s:%d: no filter queue", __func__, __LINE__);
|
if ((action = policy->kerneltable[code]) != ICPOLICY_ASK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
action = filter_evaluate(tls, pflq, ipid);
|
pflq = systrace_policyflq(policy, emulation, name);
|
||||||
if (action != ICPOLICY_ASK)
|
if (pflq == NULL)
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* 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__);
|
errx(1, "%s:%d: no filter queue", __func__, __LINE__);
|
||||||
|
|
||||||
action = filter_evaluate(tls, pflq, ipid);
|
action = filter_evaluate(tls, pflq, ipid);
|
||||||
if (action != ICPOLICY_ASK)
|
if (action != ICPOLICY_ASK)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
make_output(output, sizeof(output), binname, pid, ppid,
|
/* Do aliasing here */
|
||||||
policynr, policy->name, policy->nfilters,
|
if (!noalias)
|
||||||
alias->aemul, alias->aname, code, tls, NULL);
|
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);
|
||||||
|
if (action != ICPOLICY_ASK)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
make_output(output, sizeof(output), binname, pid, ppid,
|
||||||
|
policynr, policy->name, policy->nfilters,
|
||||||
|
alias->aemul, alias->aname, code, tls, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point, we have to ask the user, but we may check
|
||||||
|
* if the policy has been updated in the meanwhile.
|
||||||
|
*/
|
||||||
|
if (systrace_updatepolicy(fd, policy) == -1)
|
||||||
|
done = 1;
|
||||||
|
} while (!done);
|
||||||
|
|
||||||
if (policy->flags & POLICY_UNSUPERVISED) {
|
if (policy->flags & POLICY_UNSUPERVISED) {
|
||||||
action = ICPOLICY_NEVER;
|
action = ICPOLICY_NEVER;
|
||||||
|
@ -251,7 +278,7 @@ trans_cb(int fd, pid_t pid, int policynr,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (dolog)
|
if (dolog)
|
||||||
syslog(LOG_WARNING, "%s user: %s, prog: %s",
|
log_msg(LOG_WARNING, "%s user: %s, prog: %s",
|
||||||
action < ICPOLICY_NEVER ? "permit" : "deny",
|
action < ICPOLICY_NEVER ? "permit" : "deny",
|
||||||
ipid->username, output);
|
ipid->username, output);
|
||||||
|
|
||||||
|
@ -270,7 +297,8 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
|
||||||
struct filterq *pflq = NULL;
|
struct filterq *pflq = NULL;
|
||||||
short action = ICPOLICY_PERMIT;
|
short action = ICPOLICY_PERMIT;
|
||||||
short future;
|
short future;
|
||||||
int len, off, dolog = 0;
|
int off, done = 0, dolog = 0;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
ipid = NULL; /* XXXGCC -Wuninitialized [dreamcast] */
|
ipid = NULL; /* XXXGCC -Wuninitialized [dreamcast] */
|
||||||
|
|
||||||
|
@ -298,18 +326,28 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
|
||||||
if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL)
|
if ((pflq = systrace_policyflq(policy, emulation, name)) == NULL)
|
||||||
errx(1, "%s:%d: no filter queue", __func__, __LINE__);
|
errx(1, "%s:%d: no filter queue", __func__, __LINE__);
|
||||||
|
|
||||||
action = filter_evaluate(NULL, pflq, ipid);
|
do {
|
||||||
|
/* Fast-path checking */
|
||||||
|
if ((action = policy->kerneltable[code]) != ICPOLICY_ASK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (ipid->uflags & SYSCALL_LOG)
|
action = filter_evaluate(NULL, pflq, ipid);
|
||||||
dolog = 1;
|
|
||||||
|
if (action != ICPOLICY_ASK)
|
||||||
if (action != ICPOLICY_ASK)
|
goto haveresult;
|
||||||
goto out;
|
|
||||||
|
/*
|
||||||
|
* At this point, we have to ask the user, but we may check
|
||||||
|
* if the policy has been updated in the meanwhile.
|
||||||
|
*/
|
||||||
|
if (systrace_updatepolicy(fd, policy) == -1)
|
||||||
|
done = 1;
|
||||||
|
} while (!done);
|
||||||
|
|
||||||
if (policy->flags & POLICY_UNSUPERVISED) {
|
if (policy->flags & POLICY_UNSUPERVISED) {
|
||||||
action = ICPOLICY_NEVER;
|
action = ICPOLICY_NEVER;
|
||||||
dolog = 1;
|
dolog = 1;
|
||||||
goto out;
|
goto haveresult;
|
||||||
}
|
}
|
||||||
|
|
||||||
action = filter_ask(fd, NULL, pflq, policynr, emulation, name,
|
action = filter_ask(fd, NULL, pflq, policynr, emulation, name,
|
||||||
|
@ -324,12 +362,16 @@ gen_cb(int fd, pid_t pid, int policynr, const char *name, int code,
|
||||||
kill(pid, SIGKILL);
|
kill(pid, SIGKILL);
|
||||||
return (ICPOLICY_NEVER);
|
return (ICPOLICY_NEVER);
|
||||||
}
|
}
|
||||||
out:
|
haveresult:
|
||||||
|
if (ipid->uflags & SYSCALL_LOG)
|
||||||
|
dolog = 1;
|
||||||
|
|
||||||
if (dolog)
|
if (dolog)
|
||||||
syslog(LOG_WARNING, "%s user: %s, prog: %s",
|
syslog(LOG_WARNING, "%s user: %s, prog: %s",
|
||||||
action < ICPOLICY_NEVER ? "permit" : "deny",
|
action < ICPOLICY_NEVER ? "permit" : "deny",
|
||||||
ipid->username, output);
|
ipid->username, output);
|
||||||
|
|
||||||
|
out:
|
||||||
return (action);
|
return (action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,17 +456,35 @@ child_handler(int sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (wait4(-1, &status, WNOHANG, NULL) > 0)
|
while (wait4(-1, &status, WNOHANG, NULL) > 0)
|
||||||
;
|
continue;
|
||||||
|
|
||||||
errno = s;
|
errno = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
log_msg(int priority, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[_POSIX2_LINE_MAX];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
if (logtofile) {
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
fprintf(logfile, "%s: %s\n", getprogname(), buf);
|
||||||
|
} else
|
||||||
|
vsyslog(priority, fmt, ap);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: systrace [-AaCitUu] [-c uid:gid] [-d policydir] [-f file]\n"
|
"Usage: %s [-AaCeitUuV] [-c user:group] [-d policydir] "
|
||||||
"\t [-g gui] [-p pid] command ...\n");
|
"[-E logfile]\n\t [-f file] [-g gui] [-p pid] command ...\n",
|
||||||
|
getprogname());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,6 +620,35 @@ get_uid_gid(const char *argument, uid_t *uid, gid_t *gid)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
systrace_timeout(int fd, short what, void *arg)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
/* Reschedule timeout */
|
||||||
|
timerclear(&tv);
|
||||||
|
tv.tv_sec = SYSTRACE_UPDATETIME;
|
||||||
|
evtimer_add(&ev_timeout, &tv);
|
||||||
|
|
||||||
|
systrace_updatepolicies(trfd);
|
||||||
|
if (userpolicy)
|
||||||
|
systrace_dumppolicies(trfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from the kernel if something happened.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
systrace_read(int fd, short what, void *arg)
|
||||||
|
{
|
||||||
|
intercept_read(fd);
|
||||||
|
|
||||||
|
if (!intercept_existpids()) {
|
||||||
|
event_del(&ev_read);
|
||||||
|
event_del(&ev_timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -567,9 +656,9 @@ main(int argc, char **argv)
|
||||||
char **args;
|
char **args;
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
char *policypath = NULL;
|
char *policypath = NULL;
|
||||||
struct timeval tv, tv_wait;
|
struct timeval tv;
|
||||||
pid_t pidattach = 0;
|
pid_t pidattach = 0;
|
||||||
int usex11 = 1, count;
|
int usex11 = 1;
|
||||||
int background;
|
int background;
|
||||||
int setcredentials = 0;
|
int setcredentials = 0;
|
||||||
uid_t cr_uid;
|
uid_t cr_uid;
|
||||||
|
@ -578,11 +667,11 @@ main(int argc, char **argv)
|
||||||
cr_uid = 0; /* XXX gcc */
|
cr_uid = 0; /* XXX gcc */
|
||||||
cr_gid = 0; /* XXX gcc */
|
cr_gid = 0; /* XXX gcc */
|
||||||
|
|
||||||
tv_wait.tv_sec = 60;
|
while ((c = getopt(argc, argv, "Vc:aAeE:ituUCd:g:f:p:")) != -1) {
|
||||||
tv_wait.tv_usec = 0;
|
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "c:aAituUCd:g:f:p:")) != -1) {
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'V':
|
||||||
|
fprintf(stderr, "%s V%s\n", argv[0], VERSION);
|
||||||
|
exit(0);
|
||||||
case 'c':
|
case 'c':
|
||||||
setcredentials = 1;
|
setcredentials = 1;
|
||||||
if (get_uid_gid(optarg, &cr_uid, &cr_gid) == -1)
|
if (get_uid_gid(optarg, &cr_uid, &cr_gid) == -1)
|
||||||
|
@ -596,6 +685,16 @@ main(int argc, char **argv)
|
||||||
case 'd':
|
case 'd':
|
||||||
policypath = optarg;
|
policypath = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
logtofile = 1;
|
||||||
|
logfile = stderr;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
logtofile = 1;
|
||||||
|
logfile = fopen(optarg, "a");
|
||||||
|
if (logfile == NULL)
|
||||||
|
err(1, "Cannot open `%s' for writing", optarg);
|
||||||
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
if (automatic)
|
if (automatic)
|
||||||
usage();
|
usage();
|
||||||
|
@ -648,6 +747,10 @@ main(int argc, char **argv)
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize libevent but without kqueue because of systrace fd */
|
||||||
|
setenv("EVENT_NOKQUEUE", "yes", 0);
|
||||||
|
event_init();
|
||||||
|
|
||||||
/* Local initalization */
|
/* Local initalization */
|
||||||
systrace_initalias();
|
systrace_initalias();
|
||||||
systrace_initpolicy(filename, policypath);
|
systrace_initpolicy(filename, policypath);
|
||||||
|
@ -696,6 +799,9 @@ main(int argc, char **argv)
|
||||||
if (signal(SIGCHLD, child_handler) == SIG_ERR)
|
if (signal(SIGCHLD, child_handler) == SIG_ERR)
|
||||||
err(1, "signal");
|
err(1, "signal");
|
||||||
|
|
||||||
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
|
err(1, "signal");
|
||||||
|
|
||||||
/* Start the policy gui or cradle if necessary */
|
/* Start the policy gui or cradle if necessary */
|
||||||
if (usex11 && (!automatic && !allow)) {
|
if (usex11 && (!automatic && !allow)) {
|
||||||
if (cradle)
|
if (cradle)
|
||||||
|
@ -705,34 +811,22 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop on requests */
|
/* Register read events */
|
||||||
count = 0;
|
event_set(&ev_read, trfd, EV_READ|EV_PERSIST, systrace_read, NULL);
|
||||||
while (intercept_read(trfd) != -1) {
|
event_add(&ev_read, NULL);
|
||||||
if (!intercept_existpids())
|
|
||||||
break;
|
|
||||||
if (userpolicy) {
|
|
||||||
/* Periodically save modified policies */
|
|
||||||
if (count == 0) {
|
|
||||||
/* Set new wait time */
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
timeradd(&tv, &tv_wait, &tv);
|
|
||||||
} else if (count > 10) {
|
|
||||||
struct timeval now;
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
|
|
||||||
count = 0;
|
if (userpolicy || automatic) {
|
||||||
if (timercmp(&now, &tv, >)) {
|
evtimer_set(&ev_timeout, systrace_timeout, &ev_timeout);
|
||||||
/* Dump policy and cause new time */
|
timerclear(&tv);
|
||||||
systrace_dumppolicy();
|
tv.tv_sec = SYSTRACE_UPDATETIME;
|
||||||
continue;
|
evtimer_add(&ev_timeout, &tv);
|
||||||
}
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait for events */
|
||||||
|
event_dispatch();
|
||||||
|
|
||||||
if (userpolicy)
|
if (userpolicy)
|
||||||
systrace_dumppolicy();
|
systrace_dumppolicies(trfd);
|
||||||
|
|
||||||
close(trfd);
|
close(trfd);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: systrace.h,v 1.21 2005/08/10 18:19:21 elad Exp $ */
|
/* $NetBSD: systrace.h,v 1.22 2006/12/10 01:22:02 christos Exp $ */
|
||||||
/* $OpenBSD: systrace.h,v 1.14 2002/08/05 23:27:53 provos Exp $ */
|
/* $OpenBSD: systrace.h,v 1.14 2002/08/05 23:27:53 provos Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -99,9 +99,12 @@ struct policy {
|
||||||
const char *name;
|
const char *name;
|
||||||
char emulation[16];
|
char emulation[16];
|
||||||
|
|
||||||
|
struct timespec ts_last;
|
||||||
|
|
||||||
SPLAY_HEAD(syscalltree, policy_syscall) pflqs;
|
SPLAY_HEAD(syscalltree, policy_syscall) pflqs;
|
||||||
|
|
||||||
int policynr;
|
int policynr;
|
||||||
|
short kerneltable[INTERCEPT_MAXSYSCALLNR];
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
struct filterq filters;
|
struct filterq filters;
|
||||||
|
@ -132,6 +135,8 @@ TAILQ_HEAD(tmplqueue, template);
|
||||||
#define SYSCALL_LOG 0x04 /* Log this system call */
|
#define SYSCALL_LOG 0x04 /* Log this system call */
|
||||||
#define PROCESS_PROMPT 0x08 /* Prompt but nothing else */
|
#define PROCESS_PROMPT 0x08 /* Prompt but nothing else */
|
||||||
|
|
||||||
|
#define SYSTRACE_UPDATETIME 30 /* update policies every 30 seconds */
|
||||||
|
|
||||||
void systrace_parameters(void);
|
void systrace_parameters(void);
|
||||||
int systrace_initpolicy(char *, char *);
|
int systrace_initpolicy(char *, char *);
|
||||||
void systrace_setupdir(char *);
|
void systrace_setupdir(char *);
|
||||||
|
@ -139,20 +144,25 @@ struct template *systrace_readtemplate(char *, struct policy *,
|
||||||
struct template *);
|
struct template *);
|
||||||
void systrace_initcb(void);
|
void systrace_initcb(void);
|
||||||
struct policy *systrace_newpolicy(const char *, const char *);
|
struct policy *systrace_newpolicy(const char *, const char *);
|
||||||
|
void systrace_cleanpolicy(struct policy *);
|
||||||
void systrace_freepolicy(struct policy *);
|
void systrace_freepolicy(struct policy *);
|
||||||
int systrace_newpolicynr(int, struct policy *);
|
int systrace_newpolicynr(int, struct policy *);
|
||||||
int systrace_modifypolicy(int, int, const char *, short);
|
int systrace_modifypolicy(int, int, const char *, short);
|
||||||
struct policy *systrace_findpolicy(const char *);
|
struct policy *systrace_findpolicy(const char *);
|
||||||
|
struct policy *systrace_findpolicy_wildcard(const char *);
|
||||||
struct policy *systrace_findpolnr(int);
|
struct policy *systrace_findpolnr(int);
|
||||||
int systrace_dumppolicy(void);
|
int systrace_dumppolicies(int);
|
||||||
int systrace_readpolicy(char *);
|
int systrace_updatepolicies(int);
|
||||||
|
struct policy *systrace_readpolicy(const char *);
|
||||||
char *systrace_getpolicyfilename(const char *);
|
char *systrace_getpolicyfilename(const char *);
|
||||||
int systrace_addpolicy(const char *);
|
int systrace_addpolicy(const char *);
|
||||||
|
int systrace_updatepolicy(int, struct policy *);
|
||||||
struct filterq *systrace_policyflq(struct policy *, const char *, const char *);
|
struct filterq *systrace_policyflq(struct policy *, const char *, const char *);
|
||||||
|
char *systrace_getpolicyname(const char *);
|
||||||
|
|
||||||
int systrace_error_translate(char *);
|
int systrace_error_translate(char *);
|
||||||
|
|
||||||
#define SYSTRACE_MAXALIAS 5
|
#define SYSTRACE_MAXALIAS 10
|
||||||
|
|
||||||
struct systrace_alias {
|
struct systrace_alias {
|
||||||
SPLAY_ENTRY(systrace_alias) node;
|
SPLAY_ENTRY(systrace_alias) node;
|
||||||
|
@ -235,8 +245,10 @@ extern struct intercept_translate ic_pidname;
|
||||||
extern struct intercept_translate ic_signame;
|
extern struct intercept_translate ic_signame;
|
||||||
extern struct intercept_translate ic_fcntlcmd;
|
extern struct intercept_translate ic_fcntlcmd;
|
||||||
extern struct intercept_translate ic_memprot;
|
extern struct intercept_translate ic_memprot;
|
||||||
|
#ifdef notyet
|
||||||
|
extern struct intercept_translate ic_linux_memprot;
|
||||||
extern struct intercept_translate ic_linux_oflags;
|
extern struct intercept_translate ic_linux_oflags;
|
||||||
|
#endif
|
||||||
|
|
||||||
int requestor_start(const char *, int);
|
int requestor_start(const char *, int);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue