postgres.git / summary / log / commit / refs

commit    4069df21beb838e75e8639c47e6a9c800e3c8af5
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Fri Aug 07 05:23:28 2026 +0000

    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 8511c25fd29..bee0a5e14dc 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -553,9 +553,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: 44056f6493ac]