1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-21 15:54:08 +03:00

Fix unsafe access to BufferDescriptors

When considering a local buffer, the GetBufferDescriptor() call in
BufferGetLSNAtomic() would be retrieving a shared buffer with a bad
buffer ID.  Since the code checks whether the buffer is shared before
using the retrieved BufferDesc, this issue did not lead to any
malfunction.  Nonetheless this seems like trouble waiting to happen,
so fix it by ensuring that GetBufferDescriptor() is only called when
we know the buffer is shared.

Author: Tender Wang <tndrwang@gmail.com>
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>
Reviewed-by: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CAHewXNku-o46-9cmUgyv6LkSZ25doDrWq32p=oz9kfD8ovVJMg@mail.gmail.com
Backpatch-through: 13
This commit is contained in:
Richard Guo 2025-02-19 11:05:35 +09:00
parent 727bc6ac33
commit 49a450892a

View File

@ -3973,8 +3973,8 @@ BufferIsPermanent(Buffer buffer)
XLogRecPtr XLogRecPtr
BufferGetLSNAtomic(Buffer buffer) BufferGetLSNAtomic(Buffer buffer)
{ {
BufferDesc *bufHdr = GetBufferDescriptor(buffer - 1);
char *page = BufferGetPage(buffer); char *page = BufferGetPage(buffer);
BufferDesc *bufHdr;
XLogRecPtr lsn; XLogRecPtr lsn;
uint32 buf_state; uint32 buf_state;
@ -3988,6 +3988,7 @@ BufferGetLSNAtomic(Buffer buffer)
Assert(BufferIsValid(buffer)); Assert(BufferIsValid(buffer));
Assert(BufferIsPinned(buffer)); Assert(BufferIsPinned(buffer));
bufHdr = GetBufferDescriptor(buffer - 1);
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
lsn = PageGetLSN(page); lsn = PageGetLSN(page);
UnlockBufHdr(bufHdr, buf_state); UnlockBufHdr(bufHdr, buf_state);