public inbox for [email protected]  
help / color / mirror / Atom feed
From: Bharath Rupireddy <[email protected]>
To: SATYANARAYANA NARLAPURAM <[email protected]>
Cc: PostgreSQL Hackers <[email protected]>
Subject: Re: LockHasWaiters() crashes on fast-path locks
Date: Wed, 25 Mar 2026 15:06:14 -0700
Message-ID: <CALj2ACUKM1KQC=NHESOJw=ZgjAXgxapJfAEovKN0n3ZF8Csr5w@mail.gmail.com> (raw)
In-Reply-To: <CAHg+QDe_=ZahnRx37bzrqYenKn_S5YDQ00fTfwe-ZUmjqO=qLg@mail.gmail.com>
References: <CAHg+QDe_=ZahnRx37bzrqYenKn_S5YDQ00fTfwe-ZUmjqO=qLg@mail.gmail.com>

Hi,

On Wed, Mar 25, 2026 at 2:15 PM SATYANARAYANA NARLAPURAM
<[email protected]> wrote:
>
> 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.

Nice find! It would be good to add a test case (perhaps in an existing
test extension even though we may not commit it; it can act as a
demo).

I see that this type of lock transfer is happening for prepared
statements (see AtPrepare_Locks [1]). However, I see the proposed
patch relying on lock == NULL for detecting whether the lock was
acquired using fast-path. Although this looks correct because if the
lock or proclock pointers are NULL, this identifies that the lock was
taken using fast-path. But for consistency purposes, can we have the
same check as that of AtPrepare_Locks?

[1]
/*
* 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)

--
Bharath Rupireddy
Amazon Web Services: https://aws.amazon.com





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], [email protected]
  Subject: Re: LockHasWaiters() crashes on fast-path locks
  In-Reply-To: <CALj2ACUKM1KQC=NHESOJw=ZgjAXgxapJfAEovKN0n3ZF8Csr5w@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