postgres.git / summary / log / commit / refs

commit    f68f47fe7d66a475d934823624013bcb7fae6f01
Author:   Amit Langote <amitlan@postgresql.org>
Date:     Fri Aug 07 07:34:00 2026 +0000

    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


src/backend/utils/adt/ri_triggers.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 74774f6b2bd..19af06ee794 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -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. */ [parent: 8c0aa08c1594]