From 92c62b6294729b1edef47ce61f84b427b7099bd7 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 12 Aug 2005 19:42:45 +0000 Subject: [PATCH] Modify canonicalize_path() so if we would return a trailing "..", throw an error instead. --- src/backend/postmaster/postmaster.c | 7 +++- src/port/Makefile | 3 +- src/port/path.c | 64 ++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 6ebd63a098..850977d8d0 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -377,8 +377,11 @@ PostmasterMain(int argc, char *argv[]) char *userDoption = NULL; int i; - /* This will call exit() if strdup() fails. */ - progname = get_progname(argv[0]); + if ((progname = get_progname(argv[0])) == NULL) + { + printf(_("unable to allocate memory for program name \"%s\".\n"), progname); + ExitPostmaster(0); + } MyProcPid = PostmasterPid = getpid(); diff --git a/src/port/Makefile b/src/port/Makefile index 52b8acfb94..2aa8785029 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -31,6 +31,7 @@ LIBOBJS_SRV := $(LIBOBJS) LIBOBJS_SRV := $(patsubst dirmod.o,dirmod_srv.o, $(LIBOBJS_SRV)) LIBOBJS_SRV := $(patsubst exec.o,exec_srv.o, $(LIBOBJS_SRV)) LIBOBJS_SRV := $(patsubst getaddrinfo.o,getaddrinfo_srv.o, $(LIBOBJS_SRV)) +LIBOBJS_SRV := $(patsubst path.o,path_srv.o, $(LIBOBJS_SRV)) LIBOBJS_SRV := $(patsubst thread.o,thread_srv.o, $(LIBOBJS_SRV)) all: libpgport.a libpgport_srv.a @@ -66,7 +67,7 @@ exec_srv.o: exec.c getaddrinfo_srv.o: getaddrinfo.c $(CC) $(CFLAGS) $(subst -DFRONTEND,, $(CPPFLAGS)) -c $< -o $@ -snprintf_srv.o: snprintf.c +path_srv.o: path.c $(CC) $(CFLAGS) $(subst -DFRONTEND,, $(CPPFLAGS)) -c $< -o $@ # No thread flags for server version diff --git a/src/port/path.c b/src/port/path.c index ea8c7b5be7..17920d5619 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -13,7 +13,11 @@ *------------------------------------------------------------------------- */ -#include "c.h" +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif #include #include @@ -226,6 +230,7 @@ canonicalize_path(char *path) { char *p, *to_p; bool was_sep = false; + int pending_strips = 0; #ifdef WIN32 /* @@ -284,19 +289,38 @@ canonicalize_path(char *path) if (len > 2 && strcmp(path + len - 2, "/.") == 0) trim_directory(path); - /* - * Process only a single trailing "..", and only if ".." does - * not preceed it. - * So, we only deal with "/usr/local/..", not with "/usr/local/../..". - * We don't handle the even more complex cases, like - * "usr/local/../../..". - */ - else if (len > 3 && strcmp(path + len - 3, "/..") == 0 && - (len != 5 || strcmp(path, "../..") != 0) && - (len < 6 || strcmp(path + len - 6, "/../..") != 0)) + else if (len > 3 && strcmp(path + len - 3, "/..") == 0) { trim_directory(path); - trim_directory(path); /* remove directory above */ + pending_strips++; + } + else if (pending_strips > 0) + { + /* If path is not "", we can keep trimming. Even if path is + * "/", we can keep trimming because trim_directory never removes + * the leading separator, and the parent directory of "/" is "/". + */ + if (*path != '\0') + { + trim_directory(path); + pending_strips--; + } + else + { + /* + * If we still have pending_strips, it means the supplied path + * was exhausted and we still have more directories to move up. + * This means that the resulting path is only parents, like + * ".." or "../..". If so, callers can not handle trailing "..", + * so we exit. + */ +#ifndef FRONTEND + elog(ERROR, "relative paths (\"..\") not supported"); +#else + fprintf(stderr, _("relative paths (\"..\") not supported\n")); + exit(1); +#endif + } } else break; @@ -305,8 +329,10 @@ canonicalize_path(char *path) /* - * Extracts the actual name of the program as called - - * stripped of .exe suffix if any + * Extracts the actual name of the program as called - + * stripped of .exe suffix if any. + * The server calling this must check for NULL return + * and report the error. */ const char * get_progname(const char *argv0) @@ -329,8 +355,16 @@ get_progname(const char *argv0) progname = strdup(nodir_name); if (progname == NULL) { +#ifndef FRONTEND + /* + * No elog() support in postmaster at this stage, + * so return NULL and print error at the call. + */ + return NULL; +#else fprintf(stderr, "%s: out of memory\n", nodir_name); - exit(1); /* This could exit the postmaster */ + exit(1); +#endif } progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0'; nodir_name = progname; -- 2.39.5