From 9cf91c438b3c4fb4fa020133787bd75960c42a1c Mon Sep 17 00:00:00 2001 From: Marco Slot Date: Tue, 27 Nov 2018 11:18:49 +0100 Subject: [PATCH] Only allow transmit from pgsql_job_cache directory --- src/backend/distributed/commands/transmit.c | 6 ++++++ src/backend/distributed/worker/worker_partition_protocol.c | 7 ++++++- src/test/regress/expected/multi_multiuser.out | 3 +++ src/test/regress/expected/multi_multiuser_0.out | 3 +++ src/test/regress/sql/multi_multiuser.sql | 3 +++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/backend/distributed/commands/transmit.c b/src/backend/distributed/commands/transmit.c index fa976661c..f73b7029e 100644 --- a/src/backend/distributed/commands/transmit.c +++ b/src/backend/distributed/commands/transmit.c @@ -420,6 +420,12 @@ VerifyTransmitStmt(CopyStmt *copyStatement) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("path must be in or below the current directory")))); } + else if (!CacheDirectoryElement(fileName)) + { + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("path must be in the pgsql_job_cache directory")))); + } if (copyStatement->filename != NULL) { diff --git a/src/backend/distributed/worker/worker_partition_protocol.c b/src/backend/distributed/worker/worker_partition_protocol.c index 0482ff3a9..07e09a175 100644 --- a/src/backend/distributed/worker/worker_partition_protocol.c +++ b/src/backend/distributed/worker/worker_partition_protocol.c @@ -643,7 +643,12 @@ CacheDirectoryElement(const char *filename) appendStringInfo(directoryPath, "base/%s/", PG_JOB_CACHE_DIR); directoryPathFound = strstr(filename, directoryPath->data); - if (directoryPathFound != NULL) + + /* + * If directoryPath occurs at the beginning of the filename, then the + * pointers should now be equal. + */ + if (directoryPathFound == filename) { directoryElement = true; } diff --git a/src/test/regress/expected/multi_multiuser.out b/src/test/regress/expected/multi_multiuser.out index 4d69b69ce..75b0836c4 100644 --- a/src/test/regress/expected/multi_multiuser.out +++ b/src/test/regress/expected/multi_multiuser.out @@ -109,6 +109,9 @@ PREPARE prepare_select AS SELECT count(*) FROM test; -- not allowed to read absolute paths, even as superuser COPY "/etc/passwd" TO STDOUT WITH (format transmit); ERROR: absolute path not allowed +-- not allowed to read paths outside pgsql_job_cache, even as superuser +COPY "postgresql.conf" TO STDOUT WITH (format transmit); +ERROR: path must be in the pgsql_job_cache directory -- check full permission SET ROLE full_access; EXECUTE prepare_insert(1); diff --git a/src/test/regress/expected/multi_multiuser_0.out b/src/test/regress/expected/multi_multiuser_0.out index 69f14e281..abc717c99 100644 --- a/src/test/regress/expected/multi_multiuser_0.out +++ b/src/test/regress/expected/multi_multiuser_0.out @@ -109,6 +109,9 @@ PREPARE prepare_select AS SELECT count(*) FROM test; -- not allowed to read absolute paths, even as superuser COPY "/etc/passwd" TO STDOUT WITH (format transmit); ERROR: absolute path not allowed +-- not allowed to read paths outside pgsql_job_cache, even as superuser +COPY "postgresql.conf" TO STDOUT WITH (format transmit); +ERROR: path must be in the pgsql_job_cache directory -- check full permission SET ROLE full_access; EXECUTE prepare_insert(1); diff --git a/src/test/regress/sql/multi_multiuser.sql b/src/test/regress/sql/multi_multiuser.sql index a561d5c5b..0247cea13 100644 --- a/src/test/regress/sql/multi_multiuser.sql +++ b/src/test/regress/sql/multi_multiuser.sql @@ -87,6 +87,9 @@ PREPARE prepare_select AS SELECT count(*) FROM test; -- not allowed to read absolute paths, even as superuser COPY "/etc/passwd" TO STDOUT WITH (format transmit); +-- not allowed to read paths outside pgsql_job_cache, even as superuser +COPY "postgresql.conf" TO STDOUT WITH (format transmit); + -- check full permission SET ROLE full_access;