v2-0001-Make-buffer-descriptor-accessors-take-signed-int.patch
application/octet-stream
Filename: v2-0001-Make-buffer-descriptor-accessors-take-signed-int.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Make buffer descriptor accessors take signed int
| File | + | − |
|---|---|---|
| src/backend/storage/buffer/localbuf.c | 4 | 4 |
| src/include/storage/buf_internals.h | 6 | 2 |
From dd26589007f7532415816c5ef4ca4dd4c6d54a36 Mon Sep 17 00:00:00 2001
From: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
Date: Wed, 1 Jul 2026 08:40:48 +0000
Subject: [PATCH v2] Make buffer descriptor accessors take signed int
GetBufferDescriptor() and GetLocalBufferDescriptor() took a uint32 buffer
index. A Buffer is a signed int and callers routinely pass "buffer - 1"
or "-buffer - 1", so a malformed Buffer could silently wrap into a huge
positive index. Switch the parameter to int and add bounds assertions
(0 <= id < NBuffers / NLocBuffer) so such mistakes are caught.
The new assertion in GetLocalBufferDescriptor() exposed that
InitLocalBuffers() initializes the local buffer descriptors via
GetLocalBufferDescriptor() before publishing NLocBuffer, so the bounds
check saw NLocBuffer == 0. Establish NLocBuffer before the initialization
loop, mirroring shared buffers where NBuffers is set before
BufferManagerShmemInit() initializes the descriptors; whether local buffers
are ready for use is tracked separately via LocalBufHash.
Discussion: https://postgr.es/m/CAExHW5uzRMYVZsXXS3HXXT0fG_sNrpUhUqwP4NorhaCqH9JDhA@mail.gmail.com
---
src/backend/storage/buffer/localbuf.c | 8 ++++----
src/include/storage/buf_internals.h | 8 ++++++--
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index 4870c8e13d0..06bb2b65318 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -42,7 +42,7 @@ typedef struct
#define LocalBufHdrGetBlock(bufHdr) \
LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
-int NLocBuffer = 0; /* until buffers are initialized */
+int NLocBuffer = 0; /* until buffers are allocated */
BufferDesc *LocalBufferDescriptors = NULL;
Block *LocalBufferBlockPointers = NULL;
@@ -777,6 +777,9 @@ InitLocalBuffers(void)
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
+ /* Record the local buffer count now that the arrays are allocated. */
+ NLocBuffer = nbufs;
+
nextFreeLocalBufId = 0;
/* initialize fields that need to start off nonzero */
@@ -813,9 +816,6 @@ InitLocalBuffers(void)
if (!LocalBufHash)
elog(ERROR, "could not initialize local buffer hash table");
-
- /* Initialization done, mark buffers allocated */
- NLocBuffer = nbufs;
}
/*
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 89615a254a3..7b13ec0dc74 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -419,14 +419,18 @@ extern PGDLLIMPORT BufferDesc *LocalBufferDescriptors;
static inline BufferDesc *
-GetBufferDescriptor(uint32 id)
+GetBufferDescriptor(int id)
{
+ Assert(id >= 0 && id < NBuffers);
+
return &(BufferDescriptors[id]).bufferdesc;
}
static inline BufferDesc *
-GetLocalBufferDescriptor(uint32 id)
+GetLocalBufferDescriptor(int id)
{
+ Assert(id >= 0 && id < NLocBuffer);
+
return &LocalBufferDescriptors[id];
}
--
2.43.0