Sean Chittenden <chitt@speakeasy.net> writes:
> There exists a crash that could easily be used as a denial of service
> against PostgreSQL by any user who can call a trusted stored procedure
> that makes use of temp tables.
What this is actually exposing is a case where CurrentResourceOwner is
left pointing at garbage. PortalRun saves and restores the caller's
value of CurrentResourceOwner, which is normally fine and dandy.
When doing a top-level command such as the VACUUM, CurrentResourceOwner
is TopTransactionResourceOwner. However, VACUUM does internal
CommitTransaction and StartTransaction commands, which destroy and
recreate the whole transaction including TopTransactionResourceOwner.
In many situations TopTransactionResourceOwner ends up getting recreated
at the same address it was at before, but this is obviously not
guaranteeable in the general case; Sean's test case simply exposes one
path in which it isn't at the same address.
What I'm thinking of doing to fix it is having PortalRun note whether
the saved value of CurrentResourceOwner is the same as (the original
value of) TopTransactionResourceOwner, and at exit restore to the
current value of TopTransactionResourceOwner if so. This is pretty
grotty but should cure the problem. Anyone see another low-impact fix?
In the long run perhaps we should get rid of the idea of internal
transaction start/commits in VACUUM et al, or at least reduce them to be
just "partial commits" that don't go through the full CommitTransaction
process and in particular don't destroy major amounts of backend
internal state. The whole thing is just too reminiscent of Wiley Coyote
sawing off the tree limb that he's standing on.
regards, tom lane