From 44fafa6076a2108043e67ac76777c1c20664ea78 Mon Sep 17 00:00:00 2001 From: Michael Paquier 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