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

Commit51fed14

Browse files
committed
Don't get confused if a WAL partial record header has xl_tot_len == 0.
If a WAL record header was split across pages, but xl_tot_len was 0, wewould get confused and conclude that we had already read the whole record,and proceed to CRC check it. That can lead to a crash in RecordIsValid(),which isn't careful to not read beyond end-of-record, as defined byxl_tot_len.Add an explicit sanity check for xl_tot_len <= SizeOfXlogRecord. Also,make RecordIsValid() more robust by checking in each step that it doesn'ttry to access memory beyond end of record, even if a length field in therecord's or a backup block's header is bogus.Per report and analysis by Tom Lane.
1 parent9b2a237 commit51fed14

File tree

1 file changed

+36
-2
lines changed
  • src/backend/access/transam

1 file changed

+36
-2
lines changed

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,8 +3707,17 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
37073707
uint32len=record->xl_len;
37083708
BkpBlockbkpb;
37093709
char*blk;
3710+
char*recend= (char*)record+record->xl_tot_len;
37103711

37113712
/* First the rmgr data */
3713+
if (XLogRecGetData(record)+len>recend)
3714+
{
3715+
/* ValidXLogRecordHeader() should've caught this already... */
3716+
ereport(emode_for_corrupt_record(emode,recptr),
3717+
(errmsg("invalid record length at %X/%X",
3718+
(uint32) (recptr >>32), (uint32)recptr)));
3719+
return false;
3720+
}
37123721
INIT_CRC32(crc);
37133722
COMP_CRC32(crc,XLogRecGetData(record),len);
37143723

@@ -3721,7 +3730,15 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
37213730
if (!(record->xl_info&XLR_SET_BKP_BLOCK(i)))
37223731
continue;
37233732

3733+
if (blk+sizeof(BkpBlock)>recend)
3734+
{
3735+
ereport(emode_for_corrupt_record(emode,recptr),
3736+
(errmsg("incorrect backup block size in record at %X/%X",
3737+
(uint32) (recptr >>32), (uint32)recptr)));
3738+
return false;
3739+
}
37243740
memcpy(&bkpb,blk,sizeof(BkpBlock));
3741+
37253742
if (bkpb.hole_offset+bkpb.hole_length>BLCKSZ)
37263743
{
37273744
ereport(emode_for_corrupt_record(emode,recptr),
@@ -3730,6 +3747,14 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode)
37303747
return false;
37313748
}
37323749
blen=sizeof(BkpBlock)+BLCKSZ-bkpb.hole_length;
3750+
3751+
if (blk+blen>recend)
3752+
{
3753+
ereport(emode_for_corrupt_record(emode,recptr),
3754+
(errmsg("invalid backup block size in record at %X/%X",
3755+
(uint32) (recptr >>32), (uint32)recptr)));
3756+
return false;
3757+
}
37333758
COMP_CRC32(crc,blk,blen);
37343759
blk+=blen;
37353760
}
@@ -3879,8 +3904,8 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38793904

38803905
/*
38813906
* If the whole record header is on this page, validate it immediately.
3882-
* Otherwisevalidate it after reading the rest of the header from next
3883-
* page.
3907+
* Otherwiseonly do a basic sanity check on xl_tot_len, and validate the
3908+
*rest of the header after reading it from the nextpage.
38843909
*/
38853910
if (targetRecOff <=XLOG_BLCKSZ-SizeOfXLogRecord)
38863911
{
@@ -3889,7 +3914,16 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38893914
gotheader= true;
38903915
}
38913916
else
3917+
{
3918+
if (total_len<SizeOfXLogRecord)
3919+
{
3920+
ereport(emode_for_corrupt_record(emode,*RecPtr),
3921+
(errmsg("invalid record length at %X/%X",
3922+
(uint32) ((*RecPtr) >>32), (uint32)*RecPtr)));
3923+
gotonext_record_is_invalid;
3924+
}
38923925
gotheader= false;
3926+
}
38933927

38943928
/*
38953929
* Allocate or enlarge readRecordBuf as needed. To avoid useless small

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp