($INBOX_DIR/description missing)
help / color / mirror / Atom feedFrom: Noah Misch <[email protected]>
Subject: [PATCH] In REFRESH MATERIALIZED VIEW, set user ID before running user code.
Date: Mon, 9 May 2022 08:35:08 -0700
It intended to, but did not, achieve this. Adopt the new standard of
setting user ID just after locking the relation. Back-patch to v10 (all
supported versions).
Reviewed by Simon Riggs. Reported by Alvaro Herrera.
Security: CVE-2022-1552
---
src/backend/commands/matview.c | 30 +++++++++++-------------------
src/test/regress/expected/privileges.out | 15 +++++++++++++++
src/test/regress/sql/privileges.sql | 16 ++++++++++++++++
3 files changed, 42 insertions(+), 19 deletions(-)
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -164,6 +164,17 @@
lockmode, false, false,
RangeVarCallbackOwnsTable, NULL);
matviewRel = heap_open(matviewOid, NoLock);
+ relowner = matviewRel->rd_rel->relowner;
+
+ /*
+ * Switch to the owner's userid, so that any functions are run as that
+ * user. Also lock down security-restricted operations and arrange to
+ * make GUC variable changes local to this command.
+ */
+ GetUserIdAndSecContext(&save_userid, &save_sec_context);
+ SetUserIdAndSecContext(relowner,
+ save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ save_nestlevel = NewGUCNestLevel();
/* Make sure it is a materialized view. */
if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW)
@@ -269,19 +280,6 @@
*/
SetMatViewPopulatedState(matviewRel, !stmt->skipData);
- relowner = matviewRel->rd_rel->relowner;
-
- /*
- * Switch to the owner's userid, so that any functions are run as that
- * user. Also arrange to make GUC variable changes local to this command.
- * Don't lock it down too tight to create a temporary table just yet. We
- * will switch modes when we are about to execute user code.
- */
- GetUserIdAndSecContext(&save_userid, &save_sec_context);
- SetUserIdAndSecContext(relowner,
- save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
- save_nestlevel = NewGUCNestLevel();
-
/* Concurrent refresh builds new data in temp tablespace, and does diff. */
if (concurrent)
{
@@ -304,12 +302,6 @@
LockRelationOid(OIDNewHeap, AccessExclusiveLock);
dest = CreateTransientRelDestReceiver(OIDNewHeap);
- /*
- * Now lock down security-restricted operations.
- */
- SetUserIdAndSecContext(relowner,
- save_sec_context | SECURITY_RESTRICTED_OPERATION);
-
/* Generate the data, if wanted. */
if (!stmt->skipData)
refresh_matview_datafill(dest, dataQuery, queryString);
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -1323,6 +1323,21 @@
SQL statement "SELECT unwanted_grant()"
PL/pgSQL function sro_trojan() line 1 at PERFORM
SQL function "mv_action" statement 1
+-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions()
+SET SESSION AUTHORIZATION regress_sro_user;
+CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
+ IMMUTABLE LANGUAGE plpgsql AS $$
+BEGIN
+ PERFORM unwanted_grant();
+ RAISE WARNING 'owned';
+ RETURN 1;
+EXCEPTION WHEN OTHERS THEN
+ RETURN 2;
+END$$;
+CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c;
+CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0;
+\c -
+REFRESH MATERIALIZED VIEW sro_index_mv;
DROP OWNED BY regress_sro_user;
DROP ROLE regress_sro_user;
-- Admin options
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -824,6 +824,22 @@
REFRESH MATERIALIZED VIEW sro_mv;
BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT;
+-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions()
+SET SESSION AUTHORIZATION regress_sro_user;
+CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
+ IMMUTABLE LANGUAGE plpgsql AS $$
+BEGIN
+ PERFORM unwanted_grant();
+ RAISE WARNING 'owned';
+ RETURN 1;
+EXCEPTION WHEN OTHERS THEN
+ RETURN 2;
+END$$;
+CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c;
+CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0;
+\c -
+REFRESH MATERIALIZED VIEW sro_index_mv;
+
DROP OWNED BY regress_sro_user;
DROP ROLE regress_sro_user;
--Gfegn71+neI+QTr7
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="CVE-2022-1552_88b39e6148_adapted_for_9.6.patch"
view thread (5+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH] In REFRESH MATERIALIZED VIEW, set user ID before running user code.
In-Reply-To: <no-message-id-1858689@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox