Fix unsafe coding in ResourceOwnerReleaseAll()

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Cc: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Subject: Fix unsafe coding in ResourceOwnerReleaseAll()
Date: 2026-06-22 19:45:15
Message-ID: 646741.1782157515@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I wondered why the example shown in [1] led to a double-free crash
rather than a clean failure. On investigation, the problem is that
ResourceOwnerReleaseAll() calls the resource kind's ReleaseResource
method before deleting the resource from the owner, rather than
afterwards as the code in ResourceOwnerReleaseAllOfKind() does.
So if we throw an error inside ReleaseResource, the subsequent abort
cleanup comes back and does resource owner cleanup again, and we
try to delete the item again. Kaboom.

The attached patch converts the bug example into a clean failure,
even with the recent bug fix in pgcrypto undone:

regression=# SELECT encrypt_iv(
repeat('A', 1073741308)::bytea,
decode('00112233445566778899aabbccddeeff', 'hex'),
decode('000102030405060708090a0b0c0d0e0f', 'hex'),
'aes'
);
ERROR: invalid memory alloc request size 1073741824
WARNING: AbortTransaction while in ABORT state
ERROR: ResourceOwnerForget called for pgcrypto OpenSSL cipher handle after release started
regression=#

Of course, this might lead to leaking the resource we wished to free.
But that's better than crashing, or at least that's the value judgment
we made long ago in the original ResourceOwner code.

regards, tom lane

[1] https://www.postgresql.org/message-id/19527-6e7686960c6dce78%40postgresql.org

Attachment Content-Type Size
make-ResourceOwnerReleaseAll-safer.patch text/x-diff 1.4 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2026-06-22 20:03:56 Re: 048_vacuum_horizon_floor.pl hangs due to wakeup lost inside LockBufferForCleanup
Previous Message Christophe Pettus 2026-06-22 19:39:36 The PostgreSQL C Dialect