diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2002-07-30 03:16:41 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2002-07-30 03:16:41 +0000 |
commit | 330d3d824a4d747260e4a2072ea8c8a603b6c745 (patch) | |
tree | ede6dbc27c1803c81b0b0c484aae4f11512b9343 | |
parent | e3ef842646596e163c60e292f288af0cdfa72e81 (diff) |
solve a problem with realpath when the last component of the path is
a directory without S_IXUSR; tested by me and dugsong.
-rw-r--r-- | bin/systrace/intercept.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/bin/systrace/intercept.c b/bin/systrace/intercept.c index 3a2d3de4989..a2d447caebf 100644 --- a/bin/systrace/intercept.c +++ b/bin/systrace/intercept.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intercept.c,v 1.18 2002/07/22 04:02:39 provos Exp $ */ +/* $OpenBSD: intercept.c,v 1.19 2002/07/30 03:16:40 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -33,6 +33,7 @@ #include <sys/param.h> #include <sys/tree.h> #include <sys/wait.h> +#include <sys/stat.h> #include <signal.h> #include <stdlib.h> #include <string.h> @@ -42,6 +43,7 @@ #include <unistd.h> #include <errno.h> #include <err.h> +#include <libgen.h> #include "intercept.h" @@ -532,13 +534,52 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp) goto error; } - name = cwd; if (userp) { + static char rcwd[2*MAXPATHLEN]; + int failed = 0; /* If realpath fails then the filename does not exist */ - if (realpath(cwd, cwd) == NULL) - name = "<non-existent filename>"; - } else + if (realpath(cwd, rcwd) == NULL) { + char *dir, *file; + struct stat st; + + if (errno != EACCES) { + failed = 1; + goto out; + } + + /* Component of path could not be entered */ + if (strlcpy(rcwd, cwd, sizeof(rcwd)) >= sizeof(rcwd)) + goto error; + if ((file = basename(rcwd)) == NULL) + goto error; + if ((dir = dirname(rcwd)) == NULL) + goto error; + + /* So, try again */ + if (realpath(dir, rcwd) == NULL) { + failed = 1; + goto out; + } + if (strlcat(rcwd, "/", sizeof(rcwd)) >= sizeof(rcwd)) + goto error; + if (strlcat(rcwd, file, sizeof(rcwd)) >= sizeof(rcwd)) + goto error; + /* + * At this point, filename has to exist and has to + * be a directory. + */ + if (lstat(rcwd, &st) == -1 || !(st.st_mode & S_IFDIR)) + failed = 1; + } + out: + if (failed) + snprintf(rcwd, sizeof(rcwd), + "/<non-existent filename>: %s", cwd); + name = rcwd; + } else { simplify_path(cwd); + name = cwd; + } /* Restore working directory and change root space after realpath */ |