Blob Blame History Raw
Author: Filip Januš <fjanus@redhat.com>
Backport from release: 10.21/12.11/13.7
Upstream commit: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=a117cebd638dd02e5c2e791c25e43745f233111b
postgresql-9.2 doesn't support amcheck and brin
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=2081126
diff -ur -x '*.so' -x '*.o' -x 'cscope.*' -x '*.out' -x '*.sql' postgresql-9.2.24/src/backend/catalog/index.c postgresql-9.2.24_patched/src/backend/catalog/index.c
--- postgresql-9.2.24/src/backend/catalog/index.c	2017-11-06 23:17:39.000000000 +0100
+++ postgresql-9.2.24_patched/src/backend/catalog/index.c	2022-06-09 15:40:32.000000000 +0200
@@ -2684,7 +2684,16 @@

 	/* Open and lock the parent heap relation */
 	heapRelation = heap_open(heapId, ShareUpdateExclusiveLock);
-	/* And the target index relation */
+	/*
+	* Switch to the table owner's userid, so that any index 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(heapRelation->rd_rel->relowner,
+                           save_sec_context | SECURITY_RESTRICTED_OPERATION);
+	save_nestlevel = NewGUCNestLevel();
+
 	indexRelation = index_open(indexId, RowExclusiveLock);

 	/*
@@ -2698,16 +2707,6 @@
 	indexInfo->ii_Concurrent = true;

 	/*
-	 * Switch to the table owner's userid, so that any index 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(heapRelation->rd_rel->relowner,
-						   save_sec_context | SECURITY_RESTRICTED_OPERATION);
-	save_nestlevel = NewGUCNestLevel();
-
-	/*
 	 * Scan the index and gather up all the TIDs into a tuplesort object.
 	 */
 	ivinfo.index = indexRelation;
@@ -3112,6 +3111,9 @@
 	Oid			heapId;
 	IndexInfo  *indexInfo;
 	volatile bool skipped_constraint = false;
+	Oid         save_userid;
+	int         save_sec_context;
+	int         save_nestlevel;

 	/*
 	 * Open and lock the parent heap relation.  ShareLock is sufficient since
@@ -3121,6 +3123,16 @@
 	heapRelation = heap_open(heapId, ShareLock);

 	/*
+	 * Switch to the table owner's userid, so that any index 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(heapRelation->rd_rel->relowner,
+                           save_sec_context | SECURITY_RESTRICTED_OPERATION);
+	save_nestlevel = NewGUCNestLevel();
+
+	/*
 	 * Open the target index relation and get an exclusive lock on it, to
 	 * ensure that no one else is touching this particular index.
 	 */
@@ -3260,6 +3272,12 @@
 		heap_close(pg_index, RowExclusiveLock);
 	}

+	/* Roll back any GUC changes executed by index functions */
+	AtEOXact_GUC(false, save_nestlevel);
+
+	/* Restore userid and security context */
+	SetUserIdAndSecContext(save_userid, save_sec_context);
+
 	/* Close rels, but keep locks */
 	index_close(iRel, NoLock);
 	heap_close(heapRelation, NoLock);
diff -ur -x '*.so' -x '*.o' -x 'cscope.*' -x '*.out' -x '*.sql' postgresql-9.2.24/src/backend/commands/cluster.c postgresql-9.2.24_patched/src/backend/commands/cluster.c
--- postgresql-9.2.24/src/backend/commands/cluster.c	2017-11-06 23:17:39.000000000 +0100
+++ postgresql-9.2.24_patched/src/backend/commands/cluster.c	2022-06-09 15:41:12.000000000 +0200
@@ -258,7 +258,9 @@
 			int freeze_min_age, int freeze_table_age)
 {
 	Relation	OldHeap;
-
+	Oid		save_userid;
+	int		save_sec_context;
+	int		save_nestlevel;
 	/* Check for user-requested abort. */
 	CHECK_FOR_INTERRUPTS();

@@ -275,6 +277,16 @@
 		return;

 	/*
+	 * Switch to the table owner's userid, so that any index 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(OldHeap->rd_rel->relowner,
+                           save_sec_context | SECURITY_RESTRICTED_OPERATION);
+	save_nestlevel = NewGUCNestLevel();
+
+	/*
 	 * Since we may open a new transaction for each relation, we have to check
 	 * that the relation still is what we think it is.
 	 *
@@ -288,10 +300,10 @@
 		Form_pg_index indexForm;

 		/* Check that the user still owns the relation */
-		if (!pg_class_ownercheck(tableOid, GetUserId()))
+		if (!pg_class_ownercheck(tableOid, save_userid))
 		{
 			relation_close(OldHeap, AccessExclusiveLock);
-			return;
+			goto out;
 		}

 		/*
@@ -305,7 +317,7 @@
 		if (RELATION_IS_OTHER_TEMP(OldHeap))
 		{
 			relation_close(OldHeap, AccessExclusiveLock);
-			return;
+			goto out;
 		}

 		if (OidIsValid(indexOid))
@@ -316,7 +328,7 @@
 			if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(indexOid)))
 			{
 				relation_close(OldHeap, AccessExclusiveLock);
-				return;
+				goto out;
 			}

 			/*
@@ -326,14 +338,14 @@
 			if (!HeapTupleIsValid(tuple))		/* probably can't happen */
 			{
 				relation_close(OldHeap, AccessExclusiveLock);
-				return;
+				goto out;
 			}
 			indexForm = (Form_pg_index) GETSTRUCT(tuple);
 			if (!indexForm->indisclustered)
 			{
 				ReleaseSysCache(tuple);
 				relation_close(OldHeap, AccessExclusiveLock);
-				return;
+				goto out;
 			}
 			ReleaseSysCache(tuple);
 		}
@@ -389,6 +401,13 @@
 					 verbose);

 	/* NB: rebuild_relation does heap_close() on OldHeap */
+
+out:
+	/* Roll back any GUC changes executed by index functions */
+	AtEOXact_GUC(false, save_nestlevel);
+
+	/* Restore userid and security context */
+	SetUserIdAndSecContext(save_userid, save_sec_context);
 }

 /*
diff -ur -x '*.so' -x '*.o' -x 'cscope.*' -x '*.out' -x '*.sql' postgresql-9.2.24/src/backend/commands/indexcmds.c postgresql-9.2.24_patched/src/backend/commands/indexcmds.c
--- postgresql-9.2.24/src/backend/commands/indexcmds.c	2017-11-06 23:17:39.000000000 +0100
+++ postgresql-9.2.24_patched/src/backend/commands/indexcmds.c	2022-06-08 12:32:22.000000000 +0200
@@ -329,6 +329,11 @@
 	LOCKMODE	lockmode;
 	Snapshot	snapshot;
 	int			i;
+	Oid		root_save_userid;
+	int		root_save_sec_context;
+	int		root_save_nestlevel;
+
+	root_save_nestlevel = NewGUCNestLevel();

 	/*
 	 * count attributes in index
@@ -358,6 +363,15 @@
 	lockmode = stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock;
 	rel = heap_open(relationId, lockmode);

+	/*
+	 * Switch to the table owner's userid, so that any index functions are run
+	 * as that user.  Also lock down security-restricted operations.  We
+	 * already arranged to make GUC variable changes local to this command.
+	 */
+	GetUserIdAndSecContext(&root_save_userid, &root_save_sec_context);
+	SetUserIdAndSecContext(rel->rd_rel->relowner,
+                           root_save_sec_context | SECURITY_RESTRICTED_OPERATION);
+
 	relationId = RelationGetRelid(rel);
 	namespaceId = RelationGetNamespace(rel);

@@ -400,7 +414,7 @@
 	{
 		AclResult	aclresult;

-		aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
+		aclresult = pg_namespace_aclcheck(namespaceId, root_save_userid,
 										  ACL_CREATE);
 		if (aclresult != ACLCHECK_OK)
 			aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
@@ -427,7 +441,7 @@
 	{
 		AclResult	aclresult;

-		aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
+		aclresult = pg_tablespace_aclcheck(tablespaceId, root_save_userid,
 										   ACL_CREATE);
 		if (aclresult != ACLCHECK_OK)
 			aclcheck_error(aclresult, ACL_KIND_TABLESPACE,
@@ -610,11 +624,40 @@
 					 skip_build || stmt->concurrent,
 					 stmt->concurrent);

+    if (!OidIsValid(indexRelationId))
+    {
+        /*
+         * Roll back any GUC changes executed by index functions.  Also revert
+         * to original default_tablespace if we changed it above.
+         */
+        AtEOXact_GUC(false, root_save_nestlevel);
+
+        /* Restore userid and security context */
+        SetUserIdAndSecContext(root_save_userid, root_save_sec_context);
+
+        heap_close(rel, NoLock);
+        return indexRelationId;
+    }
+
+     /*
+     * Roll back any GUC changes executed by index functions, and keep
+     * subsequent changes local to this command.  It's barely possible that
+     * some index function changed a behavior-affecting GUC, e.g. xmloption,
+     * that affects subsequent steps.  This improves bug-compatibility with
+     * older PostgreSQL versions.  They did the AtEOXact_GUC() here for the
+     * purpose of clearing the above default_tablespace change.
+     */
+    AtEOXact_GUC(false, root_save_nestlevel);
+    root_save_nestlevel = NewGUCNestLevel();
+
 	/* Add any requested comment */
 	if (stmt->idxcomment != NULL)
 		CreateComments(indexRelationId, RelationRelationId, 0,
 					   stmt->idxcomment);

+    AtEOXact_GUC(false, root_save_nestlevel);
+    SetUserIdAndSecContext(root_save_userid, root_save_sec_context);
+
 	if (!stmt->concurrent)
 	{
 		/* Close the heap and we're done, in the non-concurrent case */
@@ -705,6 +748,16 @@
 	/* Open and lock the parent heap relation */
 	rel = heap_openrv(stmt->relation, ShareUpdateExclusiveLock);

+	/*
+         * Switch to the table owner's userid, so that any index functions are run
+         * as that user.  Also lock down security-restricted operations and
+         * arrange to make GUC variable changes local to this command.
+         */
+        GetUserIdAndSecContext(&root_save_userid, &root_save_sec_context);
+        SetUserIdAndSecContext(rel->rd_rel->relowner,
+                                                   root_save_sec_context | SECURITY_RESTRICTED_OPERATION);
+        root_save_nestlevel = NewGUCNestLevel();
+
 	/* And the target index relation */
 	indexRelation = index_open(indexRelationId, RowExclusiveLock);

@@ -720,6 +773,12 @@
 	/* Now build the index */
 	index_build(rel, indexRelation, indexInfo, stmt->primary, false);

+	/* Roll back any GUC changes executed by index functions */
+        AtEOXact_GUC(false, root_save_nestlevel);
+
+        /* Restore userid and security context */
+        SetUserIdAndSecContext(root_save_userid, root_save_sec_context);
+
 	/* Close both the relations, but keep the locks */
 	heap_close(rel, NoLock);
 	index_close(indexRelation, NoLock);

--- postgresql-9.2.24/src/test/regress/expected/privileges.out	2017-11-06 23:17:39.000000000 +0100
+++ privileges.out	2022-06-10 10:05:51.000000000 +0200
@@ -1544,9 +1544,27 @@
 
 set session role regressuser1;
 drop table dep_priv_test;
+\c -
+CREATE ROLE regress_sro_user;
+CREATE FUNCTION sro_ifun(int) RETURNS int AS $$
+BEGIN
+        RETURN(SELECT current_user);
+
+END;
+$$ LANGUAGE plpgsql IMMUTABLE;
+CREATE TABLE sro_tab (a int);
+ALTER TABLE sro_tab OWNER TO regress_sro_user;
+INSERT INTO sro_tab VALUES (1), (2), (3);
+CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0)))
+        WHERE sro_ifun(a + 10) > sro_ifun(10);
+ERROR:  invalid input syntax for integer: "regress_sro_user"
+CONTEXT:  PL/pgSQL function sro_ifun(integer) while casting return value to function's return type
 -- clean up
 \c
 drop sequence x_seq;
+DROP TABLE sro_tab;
+DROP ROLE regress_sro_user;
+DROP FUNCTION sro_ifun(int);
 DROP FUNCTION testfunc2(int);
 DROP FUNCTION testfunc4(boolean);
 DROP VIEW atestv1;

diff -ur postgresql-9.2.24/src/test/regress/sql/privileges.sql postgresql-9.2.24_patch/src/test/regress/sql/privileges.sql
--- postgresql-9.2.24/src/test/regress/sql/privileges.sql       2017-11-06 23:17:39.000000000 +0100
+++ postgresql-9.2.24_patch/src/test/regress/sql/privileges.sql 2022-06-08 10:01:35.000000000 +0200
@@ -931,6 +931,19 @@
 set session role regressuser1;
 drop table dep_priv_test;

+\c -
+CREATE ROLE regress_sro_user;
+CREATE FUNCTION sro_ifun(int) RETURNS int AS $$
+BEGIN
+        RETURN(SELECT current_user);
+
+END;
+$$ LANGUAGE plpgsql IMMUTABLE;
+CREATE TABLE sro_tab (a int);
+ALTER TABLE sro_tab OWNER TO regress_sro_user;
+INSERT INTO sro_tab VALUES (1), (2), (3);
+CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0)))
+        WHERE sro_ifun(a + 10) > sro_ifun(10);

 -- clean up

@@ -938,6 +951,10 @@

 drop sequence x_seq;

+DROP TABLE sro_tab;
+DROP ROLE regress_sro_user;
+
+DROP FUNCTION sro_ifun(int);
 DROP FUNCTION testfunc2(int);
 DROP FUNCTION testfunc4(boolean);