Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 567787f

Browse files
committed
Validate xlog record header before enlarging the work area to store it.
If the record header is garbled, we're now quite likely to notice it before we try to make a bogus memory allocation and run out of memory. That can still happen, if the xlog record is split across pages (we cannot verify the record header until reading the next page in that scenario), but this reduces the chances. An out-of-memory is treated as a corrupt record anyway, so this isn't a correctness issue, just a case of giving a better error message. Per Amit Kapila's suggestion.
1 parent 42e2ce6 commit 567787f

File tree

1 file changed

+20
-16
lines changed
  • src/backend/access/transam

1 file changed

+20
-16
lines changed

src/backend/access/transam/xlog.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3829,14 +3829,31 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38293829
}
38303830

38313831
/*
3832+
* Read the record length.
3833+
*
38323834
* NB: Even though we use an XLogRecord pointer here, the whole record
3833-
* header might not fit on this page. xl_tot_len is the first field in
3834-
* struct, so it must be on this page, but we cannot safely access any
3835-
* other fields yet.
3835+
* header might not fit on this page. xl_tot_len is the first field of
3836+
* the struct, so it must be on this page (the records are MAXALIGNed),
3837+
* but we cannot access any other fields until we've verified that we
3838+
* got the whole header.
38363839
*/
38373840
record = (XLogRecord *) (readBuf + (*RecPtr) % XLOG_BLCKSZ);
38383841
total_len = record->xl_tot_len;
38393842

3843+
/*
3844+
* If the whole record header is on this page, validate it immediately.
3845+
* Otherwise validate it after reading the rest of the header from next
3846+
* page.
3847+
*/
3848+
if (targetRecOff <= XLOG_BLCKSZ - SizeOfXLogRecord)
3849+
{
3850+
if (!ValidXLogRecordHeader(RecPtr, record, emode, randAccess))
3851+
goto next_record_is_invalid;
3852+
gotheader = true;
3853+
}
3854+
else
3855+
gotheader = false;
3856+
38403857
/*
38413858
* Allocate or enlarge readRecordBuf as needed. To avoid useless small
38423859
* increases, round its size to a multiple of XLOG_BLCKSZ, and make sure
@@ -3865,19 +3882,6 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt)
38653882
readRecordBufSize = newSize;
38663883
}
38673884

3868-
/*
3869-
* If we got the whole header already, validate it immediately. Otherwise
3870-
* we validate it after reading the rest of the header from the next page.
3871-
*/
3872-
if (targetRecOff <= XLOG_BLCKSZ - SizeOfXLogRecord)
3873-
{
3874-
if (!ValidXLogRecordHeader(RecPtr, record, emode, randAccess))
3875-
goto next_record_is_invalid;
3876-
gotheader = true;
3877-
}
3878-
else
3879-
gotheader = false;
3880-
38813885
len = XLOG_BLCKSZ - (*RecPtr) % XLOG_BLCKSZ;
38823886
if (total_len > len)
38833887
{

0 commit comments

Comments
 (0)