GetBufferDescriptor() being called for local buffers from MarkBufferDirtyHint()
Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
To: Andres Freund <andres@anarazel.de>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2026-06-06T08:07:42Z
Lists: pgsql-hackers
Attachments
- v20260606-0001-MarkBufferDirtyHint-calls-GetBufferDescrip.patch (text/x-patch) patch v20260606-0001
Hi Andres, 82467f627bd478569de04f4a3f1993098e80c812 added MarkBufferDirtyHint() which invokes GetBufferDescriptor() even for local buffers for which id < 0. Since GetBufferDescriptor() declares id as uint32, -1 is converted to a very large int32 value which is way larger than NBuffers. Thus GetBufferDescriptor() may be returning something from the BufferBlocks which probably has enough memory to accommodate that memory access. But it's a bogus BufferDesc nevertheless. We are not seeing any problem with this right now since MarkBufferDirtyHint() uses the BufferDesc only when it's a shared buffer. Right fix is to let that function handle local buffers first and then call GetBufferDescriptor() as in the attached patch. I caught this because of an Assertion added in GetBufferDescription() in my shared buffer resizing patches. I think it's worth committing that assertion and the related change to BufferManagerShmemInit() separately from shared buffer resizing patches. Included those changes in the attached patch as well. -- Best Wishes, Ashutosh Bapat
Commits
-
Switch Get[Local]BufferDescriptor() to use a signed value in input
- ba4134075a82 master landed
-
Fix MarkBufferDirtyHint() to not call GetBufferDescriptor() for local buffers
- e18b0cb7344c 19 (unreleased) landed
-
Require share-exclusive lock to set hint bits and to flush
- 82467f627bd4 19 (unreleased) cited