Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitffd1b6b

Browse files
committed
Add overflow protection for block-related data in WAL records
XLogRecordBlockHeader, the header holding the information for the datarelated to a block, tracks the length of the data appended to the WALrecord with data_length (uint16). This limitation in size was notenforced by the public routine in charge of registering the dataassembled later to form the WAL record inserted, XLogRegisterBufData().Incorrectly used, it could lead to the generation of records with someof its data overflowed. This commit adds some safeguards to preventthat for the block data, complaining immediately if attempting to add toa record block information with a size larger than UINT16_MAX, which isthe limit implied by the internal logic.Note that this also adjusts XLogRegisterData() and XLogRegisterBufData()so as the length of the WAL record data given by the caller is unsigned,matching with what gets stored in XLogRecData->len.Extracted from a larger patch by the same author. The original patchincludes more protections when assembling a record in full that will belooked at separately later.Author: Matthias van de MeentReviewed-by: Andres Freund, Heikki Linnakangas, Michael Paquier, DavidZhangDiscussion:https://postgr.es/m/CAEze2WgGiw+LZt+vHf8tWqB_6VxeLsMeoAuod0N=ij1q17n5pw@mail.gmail.com
1 parent70988b7 commitffd1b6b

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

‎src/backend/access/transam/xloginsert.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ XLogRegisterBlock(uint8 block_id, RelFileLocator *rlocator, ForkNumber forknum,
348348
* XLogRecGetData().
349349
*/
350350
void
351-
XLogRegisterData(char*data,intlen)
351+
XLogRegisterData(char*data,uint32len)
352352
{
353353
XLogRecData*rdata;
354354

@@ -386,7 +386,7 @@ XLogRegisterData(char *data, int len)
386386
* limited)
387387
*/
388388
void
389-
XLogRegisterBufData(uint8block_id,char*data,intlen)
389+
XLogRegisterBufData(uint8block_id,char*data,uint32len)
390390
{
391391
registered_buffer*regbuf;
392392
XLogRecData*rdata;
@@ -399,8 +399,16 @@ XLogRegisterBufData(uint8 block_id, char *data, int len)
399399
elog(ERROR,"no block with id %d registered with WAL insertion",
400400
block_id);
401401

402-
if (num_rdatas >=max_rdatas)
402+
/*
403+
* Check against max_rdatas and ensure we do not register more data per
404+
* buffer than can be handled by the physical data format; i.e. that
405+
* regbuf->rdata_len does not grow beyond what
406+
* XLogRecordBlockHeader->data_length can hold.
407+
*/
408+
if (num_rdatas >=max_rdatas||
409+
regbuf->rdata_len+len>UINT16_MAX)
403410
elog(ERROR,"too much WAL data");
411+
404412
rdata=&rdatas[num_rdatas++];
405413

406414
rdata->data=data;
@@ -756,12 +764,18 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
756764

757765
if (needs_data)
758766
{
767+
/*
768+
* When copying to XLogRecordBlockHeader, the length is narrowed
769+
* to an uint16. Double-check that it is still correct.
770+
*/
771+
Assert(regbuf->rdata_len <=UINT16_MAX);
772+
759773
/*
760774
* Link the caller-supplied rdata chain for this buffer to the
761775
* overall list.
762776
*/
763777
bkpb.fork_flags |=BKPBLOCK_HAS_DATA;
764-
bkpb.data_length=regbuf->rdata_len;
778+
bkpb.data_length=(uint16)regbuf->rdata_len;
765779
total_len+=regbuf->rdata_len;
766780

767781
rdt_datas_last->next=regbuf->rdata_head;

‎src/include/access/xloginsert.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ extern void XLogBeginInsert(void);
4343
externvoidXLogSetRecordFlags(uint8flags);
4444
externXLogRecPtrXLogInsert(RmgrIdrmid,uint8info);
4545
externvoidXLogEnsureRecordSpace(intmax_block_id,intndatas);
46-
externvoidXLogRegisterData(char*data,intlen);
46+
externvoidXLogRegisterData(char*data,uint32len);
4747
externvoidXLogRegisterBuffer(uint8block_id,Bufferbuffer,uint8flags);
4848
externvoidXLogRegisterBlock(uint8block_id,RelFileLocator*rlocator,
4949
ForkNumberforknum,BlockNumberblknum,char*page,
5050
uint8flags);
51-
externvoidXLogRegisterBufData(uint8block_id,char*data,intlen);
51+
externvoidXLogRegisterBufData(uint8block_id,char*data,uint32len);
5252
externvoidXLogResetInsertion(void);
5353
externboolXLogCheckBufferNeedsBackup(Bufferbuffer);
5454

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp