Re: Clarification on Role Access Rights to Table Indexes
Nathan Bossart <nathandbossart@gmail.com>
From: Nathan Bossart <nathandbossart@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Ayush Vatsa <ayushvatsa1810@gmail.com>, Robert Haas <robertmhaas@gmail.com>, "David G. Johnston" <david.g.johnston@gmail.com>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2025-09-24T15:58:25Z
Lists: pgsql-hackers, pgsql-general
Attachments
- v3-0001-fix-priv-checks-in-stats-code.patch (text/plain)
On Mon, Mar 10, 2025 at 10:15:19AM -0500, Nathan Bossart wrote: > On Sun, Mar 09, 2025 at 11:48:05AM -0400, Tom Lane wrote: >> Nathan Bossart <nathandbossart@gmail.com> writes: >>> On Sat, Mar 08, 2025 at 05:17:40PM -0500, Tom Lane wrote: >>>> ReindexIndex() faces this same problem and solves it with some >>>> very complex code that manages to get the table's lock first. >> >>> I noticed that amcheck's bt_index_check_internal() handles this problem, >>> ... >>> stats_lock_check_privileges() does something similar, but it's not as >>> cautious about the "heapid != IndexGetRelation(indrelid, false)" race >>> condition. >> >> Egad, we've already got three inconsistent implementations of this >> functionality? I think the first step must be to unify them into >> a common implementation, if at all possible. > > Agreed. I worry that trying to unify each bespoke implementation into a > single function might result in an unwieldy mess, but I'll give it a > shot... I tried to unify these, but each one seems to be just different enough to make it not worth the trouble. Instead, I took a look at each implementation: * amcheck's amcheck_lock_relation_and_check() seems correct to me. * stats_lock_check_privileges() appears to be missing the second IndexGetRelation() check after locking the table and index, so I added that in 0001. Since this code is new to v18, I proposed to back-patch 0001 there. * RangeVarCallbackForReindexIndex() was checking privileges on the table before locking it, so I reversed it in 0002. Interestingly, this caused test errors because LockRelationOid() checks for invalidation messages, so the pg_class_aclcheck() call started failing with unhelpful errors due to concurrently dropped relations. To deal with that, I switched to pg_class_aclcheck_ext() so that we can handle missing relations. Furthermore, I noticed that this callback seems to assume that as long as the index does not change between calls, its table won't, either. That's probably always true in practice, but even if it's completely true, I see no reason to rely on it. So, I simplified the code to unconditionally unlock any previously-locked table and to lock whatever IndexGetRelation() returns. This could probably be back-patched, but in the absence of any reports or any reproducible bugs, I don't think we should. * 0003 fixes pg_prewarm's privilege checks by following a similar pattern. This probably ought to get back-patched to all supported versions. -- nathan
Commits
-
Fix privilege checks for pg_prewarm() on indexes.
- fae0ce5e318e 16.11 landed
- f146eb45cb1a 14.20 landed
- a0551bc5734b 17.7 landed
- 6c03ae8d6e81 15.15 landed
- 3ccf8e9ac96e 18.1 landed
- 208927e65692 19 (unreleased) landed
- 19a64f5676bb 13.23 landed
-
Fix lookup code for REINDEX INDEX.
- 079480dc2022 19 (unreleased) landed
-
Fix redefinition of typedef RangeVar.
- 15d7dded0e93 18.1 landed
-
Fix lookups in pg_{clear,restore}_{attribute,relation}_stats().
- c8af5019bee5 18.1 landed
- 688dc6299a5b 19 (unreleased) landed
-
dblink: Avoid locking relation before privilege check.
- c9b299f6df98 19 (unreleased) landed