diff options
author | Nikolay Sturm <sturm@cvs.openbsd.org> | 2003-08-04 18:15:12 +0000 |
---|---|---|
committer | Nikolay Sturm <sturm@cvs.openbsd.org> | 2003-08-04 18:15:12 +0000 |
commit | e0db354ad043d751e66fee43bb893034200737c1 (patch) | |
tree | 26c7969593c1c4beb3016eb6a7b7b8517577b8ce | |
parent | ba654d3f3ba30bdc247f39b1bb74fb11280a2010 (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.c | 5 | ||||
-rw-r--r-- | bin/systrace/intercept.c | 65 | ||||
-rw-r--r-- | bin/systrace/intercept.h | 4 | ||||
-rw-r--r-- | bin/systrace/systrace.c | 7 |
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"); } /* |