From 0f82f53518db97771e77a646c519f5eeef5a84ad Mon Sep 17 00:00:00 2001 From: Bryan Green Date: Sat, 8 Aug 2026 13:10:29 -0500 Subject: [PATCH] Fix SIGSEGV in GrantLockLocal when OOM leaves LOCALLOCK.lockOwners NULL On the first LockAcquire for a lock tag, LockAcquireExtended() creates the LOCALLOCK entry with lockOwners set to NULL, then allocates the lockOwners array in TopMemoryContext. If that allocation fails with out of memory, the LOCALLOCK entry persists with lockOwners still NULL and maxLockOwners already set to 8. On a later acquisition of the same lock tag, the existing-entry path only checks numLockOwners against maxLockOwners (0 >= 8 is false), skips the allocation, and GrantLockLocal() dereferences the NULL lockOwners pointer. Handle a NULL lockOwners in the existing-entry path by allocating the array, matching the not-found path. Co-authored-by: Mark Dilger --- src/backend/storage/lmgr/lock.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 0608eee9eb..c32bb2d296 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -913,7 +913,15 @@ LockAcquireExtended(const LOCKTAG *locktag, else { /* Make sure there will be room to remember the lock */ - if (locallock->numLockOwners >= locallock->maxLockOwners) + if (locallock->lockOwners == NULL) + { + /* A prior acquisition left the array unallocated after OOM. */ + locallock->maxLockOwners = 8; + locallock->lockOwners = (LOCALLOCKOWNER *) + MemoryContextAlloc(TopMemoryContext, + locallock->maxLockOwners * sizeof(LOCALLOCKOWNER)); + } + else if (locallock->numLockOwners >= locallock->maxLockOwners) { int newsize = locallock->maxLockOwners * 2; -- 2.49.0