1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

Begin RI fast-path index scan under the switched user id

ri_FastPathCheck() called index_beginscan() before switching to the
referenced relation's owner for the permission check and probe.  For
btree this has no consequence, but starting the scan before the user id
switch sets a poor example for code dealing with out-of-tree access
methods, whose beginscan could observe the wrong user id.  Move
index_beginscan() after the SetUserIdAndSecContext() call.

Reported-by: Noah Misch <noah@leadboat.com>
Reviewed-by: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Discussion: https://postgr.es/m/20260705210533.ee.noahmisch@microsoft.com
Backpatch-through: 19
This commit is contained in:
Amit Langote
2026-08-07 16:34:00 +09:00
parent 8c0aa08c15
commit f68f47fe7d

View File

@@ -2828,10 +2828,6 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo,
idx_rel = index_open(riinfo->conindid, AccessShareLock);
slot = table_slot_create(pk_rel, NULL);
scandesc = index_beginscan(pk_rel, idx_rel,
snapshot, NULL,
riinfo->nkeys, 0,
SO_NONE);
GetUserIdAndSecContext(&saved_userid, &saved_sec_context);
SetUserIdAndSecContext(RelationGetForm(pk_rel)->relowner,
@@ -2840,6 +2836,17 @@ ri_FastPathCheck(RI_ConstraintInfo *riinfo,
SECURITY_NOFORCE_RLS);
ri_CheckPermissions(pk_rel);
/*
* Begin the scan under the switched user id, so that any access method
* code invoked by index_beginscan() runs as the PK relation's owner. For
* btree this has no functional consequence, but it keeps the ordering
* correct for out-of-tree access methods.
*/
scandesc = index_beginscan(pk_rel, idx_rel,
snapshot, NULL,
riinfo->nkeys, 0,
SO_NONE);
if (riinfo->fpmeta == NULL)
{
/* Reload to ensure it's valid. */
@@ -2965,9 +2972,6 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
*/
oldcxt = MemoryContextSwitchTo(fpentry->flush_cxt);
scandesc = index_beginscan(pk_rel, idx_rel, snapshot, NULL,
riinfo->nkeys, 0, SO_NONE);
GetUserIdAndSecContext(&saved_userid, &saved_sec_context);
SetUserIdAndSecContext(RelationGetForm(pk_rel)->relowner,
saved_sec_context |
@@ -2983,6 +2987,15 @@ ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel,
*/
ri_CheckPermissions(pk_rel);
/*
* Begin the scan under the switched user id, so that any access method
* code invoked by index_beginscan() runs as the PK relation's owner. For
* btree this has no functional consequence, but it keeps the ordering
* correct for out-of-tree access methods.
*/
scandesc = index_beginscan(pk_rel, idx_rel, snapshot, NULL,
riinfo->nkeys, 0, SO_NONE);
if (riinfo->fpmeta == NULL)
{
/* Reload to ensure it's valid. */