summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Sturm <sturm@cvs.openbsd.org>2003-08-04 18:15:12 +0000
committerNikolay Sturm <sturm@cvs.openbsd.org>2003-08-04 18:15:12 +0000
commite0db354ad043d751e66fee43bb893034200737c1 (patch)
tree26c7969593c1c4beb3016eb6a7b7b8517577b8ce
parentba654d3f3ba30bdc247f39b1bb74fb11280a2010 (diff)
several diffs from Niels as applied to NetBSD
monkey.org/NetBSD commit messages: - get rid of retarded CWD handling. CWD is fixed to the CWD of the systrace that started everything. - normalize file name function - normalize CWD for cases where CWD has a symlink in it. should solve problems where CWD policies would not match. - avoid warning due to name collision. - fixed contrived race condition during attachment; from marius@monkey.org itojun@ ok
-rw-r--r--bin/systrace/filter.c5
-rw-r--r--bin/systrace/intercept.c65
-rw-r--r--bin/systrace/intercept.h4
-rw-r--r--bin/systrace/systrace.c7
4 files changed, 50 insertions, 31 deletions
diff --git a/bin/systrace/filter.c b/bin/systrace/filter.c
index d26961bdd72..778522acf8b 100644
--- a/bin/systrace/filter.c
+++ b/bin/systrace/filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filter.c,v 1.28 2003/07/19 11:48:57 sturm Exp $ */
+/* $OpenBSD: filter.c,v 1.29 2003/08/04 18:15:11 sturm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -698,13 +698,14 @@ filter_expand(char *data)
char *
filter_dynamicexpand(struct intercept_pid *icpid, char *data)
{
+ extern char cwd[];
static char expand[2*MAXPATHLEN];
strlcpy(expand, data, sizeof(expand));
filter_replace(expand, sizeof(expand), "$HOME", icpid->home);
filter_replace(expand, sizeof(expand), "$USER", icpid->username);
- filter_replace(expand, sizeof(expand), "$CWD", icpid->cwd);
+ filter_replace(expand, sizeof(expand), "$CWD", cwd);
return (expand);
}
diff --git a/bin/systrace/intercept.c b/bin/systrace/intercept.c
index bb4e9edd317..a46227e007d 100644
--- a/bin/systrace/intercept.c
+++ b/bin/systrace/intercept.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intercept.c,v 1.41 2003/07/19 11:48:57 sturm Exp $ */
+/* $OpenBSD: intercept.c,v 1.42 2003/08/04 18:15:11 sturm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -73,6 +73,8 @@ static void sigusr1_handler(int);
static SPLAY_HEAD(pidtree, intercept_pid) pids;
static SPLAY_HEAD(sctree, intercept_syscall) scroot;
+static volatile int got_sigusr1 = 0;
+
/* Generic callback functions */
void (*intercept_newimagecb)(int, pid_t, int, const char *, const char *, void *) = NULL;
@@ -240,6 +242,7 @@ static void
sigusr1_handler(int signum)
{
/* all we need to do is pretend to handle it */
+ got_sigusr1 = 1;
}
void
@@ -249,8 +252,6 @@ intercept_setpid(struct intercept_pid *icpid, uid_t uid, gid_t gid)
icpid->uid = uid;
icpid->gid = gid;
- if (getcwd(icpid->cwd, sizeof(icpid->cwd)) == NULL)
- err(1, "getcwd");
if ((pw = getpwuid(icpid->uid)) == NULL) {
snprintf(icpid->username, sizeof(icpid->username),
"unknown(%d)", icpid->uid);
@@ -306,6 +307,9 @@ intercept_run(int bg, int fd, uid_t uid, gid_t gid,
/* Sleep */
sigsuspend(&none);
+ if (!got_sigusr1)
+ errx(1, "wrong signal");
+
/*
* Woken up, restore signal handling state.
*
@@ -581,18 +585,35 @@ intercept_get_string(int fd, pid_t pid, void *addr)
char *
intercept_filename(int fd, pid_t pid, void *addr, int userp)
{
- static char cwd[2*MAXPATHLEN];
- struct intercept_pid *icpid;
char *name;
- int havecwd = 0;
- name = intercept_get_string(fd, pid, addr);
- if (name == NULL)
+ if ((name = intercept_get_string(fd, pid, addr)) == NULL)
+ goto abort;
+
+ if ((name = normalize_filename(fd, pid, name, userp)) == NULL)
goto abort;
- if (intercept.setcwd(fd, pid) == -1) {
+ return (name);
+
+ abort:
+ ic_abort = 1;
+ return (NULL);
+}
+
+/*
+ * Normalizes a pathname so that Systrace policies entries are
+ * invariant to symlinks.
+ */
+
+char *
+normalize_filename(int fd, pid_t pid, char *name, int userp)
+{
+ static char cwd[2*MAXPATHLEN];
+ int havecwd = 0;
+
+ if (fd != -1 && intercept.setcwd(fd, pid) == -1) {
if (errno == EBUSY)
- goto abort;
+ return (NULL);
getcwderr:
if (strcmp(name, "/") == 0)
return (name);
@@ -606,13 +627,6 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
havecwd = 1;
}
- if (havecwd) {
- /* Update cwd for process */
- icpid = intercept_getpid(pid);
- if (strlcpy(icpid->cwd, cwd, sizeof(icpid->cwd)) >= sizeof(icpid->cwd))
- errx(1, "cwd too long");
- }
-
/* Need concatenated path for simplifypath */
if (havecwd && name[0] != '/') {
if (strlcat(cwd, "/", sizeof(cwd)) >= sizeof(cwd))
@@ -626,13 +640,17 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
if (userp != ICLINK_NONE) {
static char rcwd[2*MAXPATHLEN];
+ char *base= basename(cwd);
int failed = 0;
- if (userp == ICLINK_NOLAST) {
- char *file = basename(cwd);
+ /* The dot maybe used by rmdir("/tmp/something/.") */
+ if (strcmp(base, ".") == 0)
+ goto nolast;
+ if (userp == ICLINK_NOLAST) {
/* Check if the last component has special meaning */
- if (strcmp(file, ".") == 0 || strcmp(file, "..") == 0)
+ if (strcmp(base, "..") == 0 ||
+ strcmp(base, "/") == 0)
userp = ICLINK_ALL;
else
goto nolast;
@@ -691,7 +709,7 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
/* Restore working directory and change root space after realpath */
- if (intercept.restcwd(fd) == -1)
+ if (fd != -1 && intercept.restcwd(fd) == -1)
err(1, "%s: restcwd", __func__);
return (name);
@@ -699,10 +717,6 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp)
error:
errx(1, "%s: filename too long", __func__);
/* NOTREACHED */
-
- abort:
- ic_abort = 1;
- return (NULL);
}
void
@@ -873,7 +887,6 @@ intercept_child_info(pid_t opid, pid_t npid)
inpid->gid = ipid->gid;
strlcpy(inpid->username, ipid->username, sizeof(inpid->username));
strlcpy(inpid->home, ipid->home, sizeof(inpid->home));
- strlcpy(inpid->cwd, ipid->cwd, sizeof(inpid->cwd));
/* XXX - keeps track of emulation */
intercept.clonepid(ipid, inpid);
diff --git a/bin/systrace/intercept.h b/bin/systrace/intercept.h
index 84fd8b49c0f..805d4e5083d 100644
--- a/bin/systrace/intercept.h
+++ b/bin/systrace/intercept.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intercept.h,v 1.17 2003/06/16 06:36:40 itojun Exp $ */
+/* $OpenBSD: intercept.h,v 1.18 2003/08/04 18:15:11 sturm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -100,7 +100,6 @@ struct intercept_pid {
char username[MAXLOGNAME];
char home[MAXPATHLEN]; /* current home dir for uid */
- char cwd[MAXPATHLEN]; /* current working directory */
void *data;
@@ -185,6 +184,7 @@ struct intercept_pid *intercept_getpid(pid_t);
int intercept_existpids(void);
char *intercept_get_string(int, pid_t, void *);
+char *normalize_filename(int, pid_t, char *, int);
char *intercept_filename(int, pid_t, void *, int);
void intercept_syscall(int, pid_t, u_int16_t, int, const char *, int,
const char *, void *, int);
diff --git a/bin/systrace/systrace.c b/bin/systrace/systrace.c
index a5e5bdb8244..ec4632c749b 100644
--- a/bin/systrace/systrace.c
+++ b/bin/systrace/systrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: systrace.c,v 1.44 2003/07/19 11:48:58 sturm Exp $ */
+/* $OpenBSD: systrace.c,v 1.45 2003/08/04 18:15:11 sturm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -72,6 +72,7 @@ void
systrace_parameters(void)
{
struct passwd *pw;
+ char *normcwd;
uid_t uid = getuid();
iamroot = getuid() == 0;
@@ -87,6 +88,10 @@ systrace_parameters(void)
/* Determine current working directory for filtering */
if (getcwd(cwd, sizeof(cwd)) == NULL)
err(1, "getcwd");
+ if ((normcwd = normalize_filename(-1, 0, cwd, ICLINK_ALL)) == NULL)
+ errx(1, "normalize_filename");
+ if (strlcpy(cwd, normcwd, sizeof(cwd)) >= sizeof(cwd))
+ errx(1, "cwd too long");
}
/*