From 44fafa6076a2108043e67ac76777c1c20664ea78 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Fri, 9 Mar 2018 16:43:06 +0900
Subject: [PATCH] Fix missing schema qualifications in code

Per CVE-2018-1058, not using proper schema qualifications can allow an
attacker who has an account on the server to execute arbitrary code as a
superuser even if he has no such rights.  After monitoring the whole
code of Postgres, I have bumped into four places that need to be
addressed:
- isolationtester is missing one qualification when calling
pg_backend_pid.
- psql is missing two qualifications for array_remove
- information_schema.sql has one problem within function
_pg_interval_type
- worker_spi scans pg_namespace and uses count() without
qualifications.
---
 src/backend/catalog/information_schema.sql | 2 +-
 src/bin/psql/command.c                     | 2 +-
 src/test/isolation/isolationtester.c       | 2 +-
 src/test/modules/worker_spi/worker_spi.c   | 4 +++-
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index f4e69f4a26..4f2af408ac 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -186,7 +186,7 @@ CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text
     AS
 $$SELECT
   CASE WHEN $1 IN (1186) /* interval */
-           THEN upper(substring(format_type($1, $2) from 'interval[()0-9]* #"%#"' for '#'))
+           THEN pg_catalog.upper(substring(pg_catalog.format_type($1, $2) from 'interval[()0-9]* #"%#"' for '#'))
        ELSE null
   END$$;
 
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 3560318749..f345572c8c 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -4483,7 +4483,7 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid,
 				printfPQExpBuffer(query,
 								  "SELECT nspname, relname, relkind, "
 								  "pg_catalog.pg_get_viewdef(c.oid, true), "
-								  "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
+								  "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
 								  "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
 								  "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption "
 								  "FROM pg_catalog.pg_class c "
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 4ecad038bd..64d666f5cd 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -184,7 +184,7 @@ main(int argc, char **argv)
 		PQclear(res);
 
 		/* Get the backend pid for lock wait checking. */
-		res = PQexec(conns[i], "SELECT pg_backend_pid()");
+		res = PQexec(conns[i], "SELECT pg_catalog.pg_backend_pid()");
 		if (PQresultStatus(res) == PGRES_TUPLES_OK)
 		{
 			if (PQntuples(res) == 1 && PQnfields(res) == 1)
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index 3b98b1682b..547bdb26c4 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -115,7 +115,9 @@ initialize_worker_spi(worktable *table)
 
 	/* XXX could we use CREATE SCHEMA IF NOT EXISTS? */
 	initStringInfo(&buf);
-	appendStringInfo(&buf, "select count(*) from pg_namespace where nspname = '%s'",
+	appendStringInfo(&buf,
+					 "select pg_catalog.count(*) "
+					 "from pg_catalog.pg_namespace where nspname = '%s'",
 					 table->schema);
 
 	ret = SPI_execute(buf.data, true, 0);
-- 
2.16.2

