{
int mode;
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for open: \"%s\"", path);
+
if (dry_run)
return;
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for removal: \"%s\"", path);
+
if (dry_run)
return;
char dstpath[MAXPGPATH];
int fd;
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target file path is unsafe for truncation: \"%s\"", path);
+
if (dry_run)
return;
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target directory path is unsafe for directory creation: \"%s\"",
+ path);
+
if (dry_run)
return;
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target directory path is unsafe for directory removal: \"%s\"",
+ path);
+
if (dry_run)
return;
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target symlink path is unsafe for creation: \"%s\"", path);
+
if (dry_run)
return;
{
char dstpath[MAXPGPATH];
+ if (!path_is_safe_for_extraction(path))
+ pg_fatal("target symlink path is unsafe for removal: \"%s\"", path);
+
if (dry_run)
return;
extern void cleanup_path(char *path);
extern bool path_contains_parent_reference(const char *path);
extern bool path_is_relative_and_below_cwd(const char *path);
+extern bool path_is_safe_for_extraction(const char *path);
extern bool path_is_prefix_of_path(const char *path1, const char *path2);
extern char *make_absolute_path(const char *path);
extern const char *get_progname(const char *argv0);
return true;
}
+/*
+ * Detect whether a path is safe for use during archive extraction.
+ *
+ * This applies canonicalize_path(), then it checks that the path does
+ * not contain any parent directory references.
+ */
+bool
+path_is_safe_for_extraction(const char *path)
+{
+ char buf[MAXPGPATH];
+
+ strlcpy(buf, path, sizeof(buf));
+ canonicalize_path(buf);
+
+ return path_is_relative_and_below_cwd(buf);
+}
+
/*
* Detect whether path1 is a prefix of path2 (including equality).
*