Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0de0cc1

Browse files
committed
Properly handle Win32 paths of 'E:abc', which can be either absolute or
relative, by creating a function path_is_relative_and_below_cwd() tocheck for specific requirements. It is unclear if this fixes a securityproblem or not but the new code is more robust.
1 parentb313bca commit0de0cc1

File tree

4 files changed

+73
-48
lines changed

4 files changed

+73
-48
lines changed

‎contrib/adminpack/adminpack.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,32 +73,30 @@ convert_and_check_filename(text *arg, bool logAllowed)
7373

7474
canonicalize_path(filename);/* filename can change length here */
7575

76-
/* Disallow ".." in the path */
77-
if (path_contains_parent_reference(filename))
78-
ereport(ERROR,
79-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
80-
(errmsg("reference to parent directory (\"..\") not allowed"))));
81-
8276
if (is_absolute_path(filename))
8377
{
84-
/* Allow absolute references within DataDir */
85-
if (path_is_prefix_of_path(DataDir,filename))
86-
returnfilename;
87-
/* The log directory might be outside our datadir, but allow it */
88-
if (logAllowed&&
89-
is_absolute_path(Log_directory)&&
90-
path_is_prefix_of_path(Log_directory,filename))
91-
returnfilename;
92-
93-
ereport(ERROR,
78+
/* Disallow '/a/b/data/..' */
79+
if (path_contains_parent_reference(filename))
80+
ereport(ERROR,
81+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
82+
(errmsg("reference to parent directory (\"..\") not allowed"))));
83+
/*
84+
*Allow absolute paths if within DataDir or Log_directory, even
85+
*though Log_directory might be outside DataDir.
86+
*/
87+
if (!path_is_prefix_of_path(DataDir,filename)&&
88+
(!logAllowed|| !is_absolute_path(Log_directory)||
89+
!path_is_prefix_of_path(Log_directory,filename)))
90+
ereport(ERROR,
9491
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
9592
(errmsg("absolute path not allowed"))));
96-
returnNULL;/* keep compiler quiet */
97-
}
98-
else
99-
{
100-
returnfilename;
10193
}
94+
elseif (!path_is_relative_and_below_cwd(filename))
95+
ereport(ERROR,
96+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
97+
(errmsg("path must be in or below the current directory"))));
98+
99+
returnfilename;
102100
}
103101

104102

‎src/backend/utils/adt/genfile.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,31 +51,30 @@ convert_and_check_filename(text *arg)
5151
filename=text_to_cstring(arg);
5252
canonicalize_path(filename);/* filename can change length here */
5353

54-
/* Disallow ".." in the path */
55-
if (path_contains_parent_reference(filename))
56-
ereport(ERROR,
57-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
58-
(errmsg("reference to parent directory (\"..\") not allowed"))));
59-
6054
if (is_absolute_path(filename))
6155
{
62-
/* Allow absolute references within DataDir */
63-
if (path_is_prefix_of_path(DataDir,filename))
64-
returnfilename;
65-
/* The log directory might be outside our datadir, but allow it */
66-
if (is_absolute_path(Log_directory)&&
67-
path_is_prefix_of_path(Log_directory,filename))
68-
returnfilename;
69-
70-
ereport(ERROR,
56+
/* Disallow '/a/b/data/..' */
57+
if (path_contains_parent_reference(filename))
58+
ereport(ERROR,
59+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
60+
(errmsg("reference to parent directory (\"..\") not allowed"))));
61+
/*
62+
*Allow absolute paths if within DataDir or Log_directory, even
63+
*though Log_directory might be outside DataDir.
64+
*/
65+
if (!path_is_prefix_of_path(DataDir,filename)&&
66+
(!is_absolute_path(Log_directory)||
67+
!path_is_prefix_of_path(Log_directory,filename)))
68+
ereport(ERROR,
7169
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
7270
(errmsg("absolute path not allowed"))));
73-
returnNULL;/* keep compiler quiet */
74-
}
75-
else
76-
{
77-
returnfilename;
7871
}
72+
elseif (!path_is_relative_and_below_cwd(filename))
73+
ereport(ERROR,
74+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
75+
(errmsg("path must be in or below the current directory"))));
76+
77+
returnfilename;
7978
}
8079

8180

‎src/include/port.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ extern void join_path_components(char *ret_path,
4242
externvoidcanonicalize_path(char*path);
4343
externvoidmake_native_path(char*path);
4444
externboolpath_contains_parent_reference(constchar*path);
45+
externboolpath_is_relative_and_below_cwd(constchar*path);
4546
externboolpath_is_prefix_of_path(constchar*path1,constchar*path2);
4647
externconstchar*get_progname(constchar*argv0);
4748
externvoidget_share_path(constchar*my_exec_path,char*ret_path);
@@ -77,13 +78,7 @@ extern void pgfnames_cleanup(char **filenames);
7778
#else
7879
#defineIS_DIR_SEP(ch)((ch) == '/' || (ch) == '\\')
7980

80-
/*
81-
* On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is
82-
* relative to the cwd on that drive, or the drive's root directory
83-
* if that drive has no cwd. Because the path itself cannot tell us
84-
* which is the case, we have to assume the worst, i.e. that it is not
85-
* absolute; this check is done by IS_DIR_SEP(filename[2]).
86-
*/
81+
/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */
8782
#defineis_absolute_path(filename) \
8883
( \
8984
IS_DIR_SEP((filename)[0]) || \

‎src/port/path.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,39 @@ path_contains_parent_reference(const char *path)
358358
return false;
359359
}
360360

361+
/*
362+
* Detect whether a path is only in or below the current working directory.
363+
* An absolute path that matches the current working directory should
364+
* return false (we only want relative to the cwd). We don't allow
365+
* "/../" even if that would keep us under the cwd (it is too hard to
366+
* track that).
367+
*/
368+
bool
369+
path_is_relative_and_below_cwd(constchar*path)
370+
{
371+
if (!is_absolute_path(path))
372+
return false;
373+
/* don't allow anything above the cwd */
374+
elseif (path_contains_parent_reference(path))
375+
return false;
376+
#ifdefWIN32
377+
/*
378+
*On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is
379+
*relative to the cwd on that drive, or the drive's root directory
380+
*if that drive has no cwd. Because the path itself cannot tell us
381+
*which is the case, we have to assume the worst, i.e. that it is not
382+
*below the cwd. We could use GetFullPathName() to find the full path
383+
*but that could change if the current directory for the drive changes
384+
*underneath us, so we just disallow it.
385+
*/
386+
elseif (isalpha((unsignedchar)path[0])&&path[1]==':'&&
387+
!IS_DIR_SEP(path[2]))
388+
return false;
389+
#endif
390+
else
391+
returntrue;
392+
}
393+
361394
/*
362395
* Detect whether path1 is a prefix of path2 (including equality).
363396
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp