diff options
author | Bruce Momjian <bruce@momjian.us> | 2011-02-12 09:47:51 -0500 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2011-02-12 09:47:51 -0500 |
commit | 0de0cc150af46122238f2fe03605bf14e1a7c276 (patch) | |
tree | 1af197eca1a70339335f4243b371d6d4d159cee1 /src/backend/utils/adt/genfile.c | |
parent | b313bca0afce3ab9dab0a77c64c0982835854b9a (diff) | |
download | postgresql-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/backend/utils/adt/genfile.c')
-rw-r--r-- | src/backend/utils/adt/genfile.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index c3ec98aa5e2..7c59e9a20ef 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -51,31 +51,30 @@ convert_and_check_filename(text *arg) filename = text_to_cstring(arg); canonicalize_path(filename); /* filename can change length here */ - /* Disallow ".." in the path */ - if (path_contains_parent_reference(filename)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("reference to parent directory (\"..\") not allowed")))); - if (is_absolute_path(filename)) { - /* Allow absolute references within DataDir */ - if (path_is_prefix_of_path(DataDir, filename)) - return filename; - /* The log directory might be outside our datadir, but allow it */ - if (is_absolute_path(Log_directory) && - path_is_prefix_of_path(Log_directory, filename)) - return filename; - - ereport(ERROR, + /* Disallow '/a/b/data/..' */ + if (path_contains_parent_reference(filename)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("reference to parent directory (\"..\") not allowed")))); + /* + * Allow absolute paths if within DataDir or Log_directory, even + * though Log_directory might be outside DataDir. + */ + if (!path_is_prefix_of_path(DataDir, filename) && + (!is_absolute_path(Log_directory) || + !path_is_prefix_of_path(Log_directory, filename))) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("absolute path not allowed")))); - return NULL; /* keep compiler quiet */ - } - else - { - return filename; } + else if (!path_is_relative_and_below_cwd(filename)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("path must be in or below the current directory")))); + + return filename; } |