| From: | Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com> |
|---|---|
| To: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
| Cc: | Robert Haas <robertmhaas(at)gmail(dot)com>, Jeff Davis <pgsql(at)j-davis(dot)com>, Roman Eskin <r(dot)eskin(at)arenadata(dot)io>, Michael Paquier <michael(at)paquier(dot)xyz>, Alexander Lakhin <exclusion(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
| Subject: | Re: Avoid orphaned objects dependencies, take 3 |
| Date: | 2026-06-01 09:21:39 |
| Message-ID: | ah1PIyqtT+427dWb@bdtpg |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
On Wed, May 27, 2026 at 06:53:35PM +0300, Heikki Linnakangas wrote:
> Fixed these, and did some more copy-editing on the comments. With that,
> committed and backpatched.
Thanks!
Now that we avoid orphaned objects dependencies, I resumed working on Robert's
concern about the TOCTOU window where a REVOKE could land between the original
permission check and the dependency recording.
Based on our discussion during PGConf.dev, PFA a new patch that uses the same
approach as RangeVarGetRelidExtended(): record SharedInvalidMessageCounter at the
time of the original aclcheck, then before locking compare the current counter to
the saved value. If it changed, recheck permission before acquiring the lock.
After the lock wait, if more invalidations arrived, release and retry.
Remarks:
The tracking array lives in a dedicated AclCheckTrackContext memory context
(child of TopMemoryContext). The context is reset at the start of each
top-level utility statement, which frees all prior allocations and provides
clean lifetime management.
Recording is gated by aclcheck_tracking_active, which is set to true only
during top-level utility statement execution. This ensures DML and queries pay
no cost. The flag is cleared both at normal completion of ProcessUtility and in
AbortTransaction to handle the error path.
The patch adds a test that would fail without the TOCTOU protection in place.
Alternatives considered:
- To avoid allocating memory for each statement, keep the array in
TopMemoryContext and never free it (only resetting the count). But that left the
high-water mark allocated for the lifetime of the backend.
- Passing privilege info (roleId, mode) as extra arguments through the
dependency recording APIs (recordDependencyOn, recordMultipleDependencies,
etc.). It was discarded because expression-based dependencies (recordDependencyOnExpr,
find_expr_references_walker) discover objects by walking expression trees: the
caller never sees individual objects and cannot attach privilege info to them.
That's why I believe the tracking approach that is in the attached sounds like
a right approach. Bonus point, it would also help if we want to "ensure" that
we always do the acl check prior the dependency recording: that would avoid
cases like the one mentioned in [1] (for example, when we can create a view and
then record a dependency based on a function we don't have exec privilege on).
[1]: https://postgr.es/m/agsCqlLTytZCudMv%40bdtpg
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
| Attachment | Content-Type | Size |
|---|---|---|
| v23-0001-Recheck-permissions-after-lock-acquisition-in-de.patch | text/x-diff | 19.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Andrei Lepikhov | 2026-06-01 09:30:17 | Re: hashjoins vs. Bloom filters (yet again) |
| Previous Message | Ewan Young | 2026-06-01 08:41:35 | Re: autovacuum launcher crash: assert in pgstat_count_io_op (IOOP_EXTEND on pg_database's VM) |