aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/matview.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2022-05-09 08:35:08 -0700
committerNoah Misch <noah@leadboat.com>2022-05-09 08:35:13 -0700
commit34ff15660b4f752e3941d661c3896fd96b1571f9 (patch)
treeb26c1c96266481ce8b1b6f1d4667e2403bc0e680 /src/backend/commands/matview.c
parent48ca2904c11d4293ec0bed1625259b2e4ef550cc (diff)
downloadpostgresql-34ff15660b4f752e3941d661c3896fd96b1571f9.tar.gz
postgresql-34ff15660b4f752e3941d661c3896fd96b1571f9.zip
In REFRESH MATERIALIZED VIEW, set user ID before running user code.
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
Diffstat (limited to 'src/backend/commands/matview.c')
-rw-r--r--src/backend/commands/matview.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 95b22c54cc5..ce3a415d29b 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -164,6 +164,17 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
lockmode, 0,
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)
@@ -268,19 +279,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
*/
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)
{
@@ -303,12 +301,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
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)
processed = refresh_matview_datafill(dest, dataQuery, queryString);