public inbox for [email protected]
help / color / mirror / Atom feedFrom: SATYANARAYANA NARLAPURAM <[email protected]>
To: PostgreSQL Hackers <[email protected]>
Subject: LockHasWaiters() crashes on fast-path locks
Date: Wed, 25 Mar 2026 14:15:08 -0700
Message-ID: <CAHg+QDe_=ZahnRx37bzrqYenKn_S5YDQ00fTfwe-ZUmjqO=qLg@mail.gmail.com> (raw)
Hi Hackers,
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 locks (< ShareUpdateExclusiveLock) on
relations may not be stored in the shared lock hash table, and the
LOCALLOCK entry is left with lock = NULL and proclock = NULL in such a case.
If LockHasWaiters() is called for such a lock, it dereferences those NULL
pointers when it reads proclock->holdMask and lock->waitMask, causing a
segfault.
The only existing caller is lazy_truncate_heap() in VACUUM, which queries
LockHasWaitersRelation(rel, AccessExclusiveLock). Since AccessExclusiveLock
is the strongest lock level, it is never fast-pathed, so the bug has never
been triggered in practice. However, any new caller that passes a weak lock
mode, for example, checking whether a DDL is waiting on an AccessShareLock
will crash. The fix is to transfer the lock to the main lock table before
we access them.
Attached a patch to address this issue.
Thanks,
Satya
Attachments:
[application/octet-stream] 0001-lock-has-waiters-fast-path-fix.patch (829B, 3-0001-lock-has-waiters-fast-path-fix.patch)
download | inline diff:
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index d930c66c..ff9b9caa 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -743,6 +743,20 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
*/
partitionLock = LockHashPartitionLock(locallock->hashcode);
+ /*
+ * If the lock was acquired via the fast path, locallock->lock and
+ * locallock->proclock will be NULL. We must transfer the lock to the
+ * main lock table before we can inspect LOCK->waitMask.
+ */
+ if (locallock->lock == NULL)
+ {
+ PROCLOCK *fp_proclock;
+
+ fp_proclock = FastPathGetRelationLockEntry(locallock);
+ locallock->lock = fp_proclock->tag.myLock;
+ locallock->proclock = fp_proclock;
+ }
+
LWLockAcquire(partitionLock, LW_SHARED);
/*
view thread (5+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected]
Subject: Re: LockHasWaiters() crashes on fast-path locks
In-Reply-To: <CAHg+QDe_=ZahnRx37bzrqYenKn_S5YDQ00fTfwe-ZUmjqO=qLg@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox