aboutsummaryrefslogtreecommitdiff
path: root/src/port/path.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2011-02-12 09:47:51 -0500
committerBruce Momjian <bruce@momjian.us>2011-02-12 09:47:51 -0500
commit0de0cc150af46122238f2fe03605bf14e1a7c276 (patch)
tree1af197eca1a70339335f4243b371d6d4d159cee1 /src/port/path.c
parentb313bca0afce3ab9dab0a77c64c0982835854b9a (diff)
downloadpostgresql-0de0cc150af46122238f2fe03605bf14e1a7c276.tar.gz
postgresql-0de0cc150af46122238f2fe03605bf14e1a7c276.zip
Properly handle Win32 paths of 'E:abc', which can be either absolute or
relative, by creating a function path_is_relative_and_below_cwd() to check for specific requirements. It is unclear if this fixes a security problem or not but the new code is more robust.
Diffstat (limited to 'src/port/path.c')
-rw-r--r--src/port/path.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/port/path.c b/src/port/path.c
index 5b0056dfe58..e01c7b8c0e5 100644
--- a/src/port/path.c
+++ b/src/port/path.c
@@ -359,6 +359,39 @@ path_contains_parent_reference(const char *path)
}
/*
+ * Detect whether a path is only in or below the current working directory.
+ * An absolute path that matches the current working directory should
+ * return false (we only want relative to the cwd). We don't allow
+ * "/../" even if that would keep us under the cwd (it is too hard to
+ * track that).
+ */
+bool
+path_is_relative_and_below_cwd(const char *path)
+{
+ if (!is_absolute_path(path))
+ return false;
+ /* don't allow anything above the cwd */
+ else if (path_contains_parent_reference(path))
+ return false;
+#ifdef WIN32
+ /*
+ * On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is
+ * relative to the cwd on that drive, or the drive's root directory
+ * if that drive has no cwd. Because the path itself cannot tell us
+ * which is the case, we have to assume the worst, i.e. that it is not
+ * below the cwd. We could use GetFullPathName() to find the full path
+ * but that could change if the current directory for the drive changes
+ * underneath us, so we just disallow it.
+ */
+ else if (isalpha((unsigned char) path[0]) && path[1] == ':' &&
+ !IS_DIR_SEP(path[2]))
+ return false;
+#endif
+ else
+ return true;
+}
+
+/*
* Detect whether path1 is a prefix of path2 (including equality).
*
* This is pretty trivial, but it seems better to export a function than