From 35379e9079c391754e7a9f54647c84d6e2caece5 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 | 9 ++-- src/port/Makefile | 5 ++- src/port/path.c | 66 ++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 765cdf4842..4b2cd5ee95 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.464 2005/08/12 18:23:53 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.465 2005/08/12 19:42:44 momjian Exp $ * * NOTES * @@ -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 c515596767..374ec532bb 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -15,7 +15,7 @@ # for use only by the backend binaries # # IDENTIFICATION -# $PostgreSQL: pgsql/src/port/Makefile,v 1.25 2005/03/20 03:53:39 momjian Exp $ +# $PostgreSQL: pgsql/src/port/Makefile,v 1.26 2005/08/12 19:42:45 momjian Exp $ # #------------------------------------------------------------------------- @@ -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 2095db4016..ee8475fccd 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -8,12 +8,16 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/path.c,v 1.54 2005/08/12 03:07:45 momjian Exp $ + * $PostgreSQL: pgsql/src/port/path.c,v 1.55 2005/08/12 19:42:45 momjian Exp $ * *------------------------------------------------------------------------- */ -#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.40.0