From 349f3fa56abda1f9411400ae9a05efabcb2270e8 Mon Sep 17 00:00:00 2001 From: Satya Narlapuram Date: Thu, 26 Mar 2026 21:42:15 +0000 Subject: [PATCH] Fix LockHasWaiters() crash for fast-path locks LockHasWaiters() assumes that the LOCALLOCK's lock and proclock pointers are populated, but this is not the case for locks acquired via the fast-path optimization. Weak relation locks (< ShareUpdateExclusiveLock), including AccessShareLock, are not stored in the shared lock hash table, leaving the LOCALLOCK entry with lock = NULL and proclock = NULL. If LockHasWaiters() is called for such a lock, it dereferences those NULL pointers when reading proclock->holdMask and lock->waitMask, causing a segfault. Fix by checking whether the LOCALLOCK has been populated and, if not, calling FastPathGetRelationLockEntry() to transfer the lock from the fast-path arrays into the main lock table. --- src/backend/storage/lmgr/lock.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index d930c66c..3f4d343d 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -743,6 +743,17 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock) */ partitionLock = LockHashPartitionLock(locallock->hashcode); + /* + * If the local lock was taken via the fast-path, we need to move it + * to the primary lock table, or just get a pointer to the existing + * primary lock table entry if by chance it's already been transferred. + */ + if (locallock->proclock == NULL) + { + locallock->proclock = FastPathGetRelationLockEntry(locallock); + locallock->lock = locallock->proclock->tag.myLock; + } + LWLockAcquire(partitionLock, LW_SHARED); /* -- 2.43.0