postgres.git / summary / log / commit / refs
commit 89fc6a7c12f2ee6d75e6ebab06844edd4737c348
Author: Michael Paquier <michael@paquier.xyz>
Date: Fri Aug 07 05:23:33 2026 +0000
First released in: 15.19, 16.15, 17.11, 18.6
Fix local pgstat entry leak on OOM during entry creation
When pgstat_init_entry() fails due to an OOM in the DSA allocation,
pgstat_get_entry_ref() cleaned up the shared hashtable but forgot to
remove the local reference that pgstat_get_entry_ref_cached() had
already inserted into pgStatEntryRefHash.
Missing this cleanup would leave a backend with a stale local cache
entry whose entry_ref points to a NULL shared_stats. If
pgstat_gc_entry_refs() runs with this reference still around, it would
crash due to a pointer dereference.
The local reference is now removed before removing the shared entry,
the order being sensitive to pending interrupts.
Oversight in 8191e0c16a03.
Author: Niall Newman <nn@turacolabs.com>
Discussion: https://postgr.es/m/2FDAA194-9CF3-4FD7-A450-F1A4BEB125F6@turacolabs.com
Backpatch-through: 15
src/backend/utils/activity/pgstat_shmem.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/activity/pgstat_shmem.c
index 5ea3f1973f9..58b99002f3f 100644
--- a/src/backend/utils/activity/pgstat_shmem.c
+++ b/src/backend/utils/activity/pgstat_shmem.c
@@ -539,9 +539,12 @@ pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, bool create,
if (shheader == NULL)
{
/*
- * Failed the allocation of a new entry, so clean up the
- * shared hashtable before giving up.
+ * Failed the allocation of a new entry, so clean up both the
+ * local reference and the shared hashtable before giving up.
+ * Clean the local state first, since releasing the dshash
+ * lock can process a pending interrupt.
*/
+ pgstat_release_entry_ref(key, entry_ref, false);
dshash_delete_entry(pgStatLocal.shared_hash, shhashent);
ereport(ERROR,
[parent: cacba321c2ef]