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

Appearance settings

Commit becfbdd

Browse filesBrowse files
committed
Fix edge-case for xl_tot_len broken by bae868c.
bae868c removed a check that was still needed. If you had an xl_tot_len at the end of a page that was too small for a record header, but not big enough to span onto the next page, we'd immediately perform the CRC check using a bogus large length. Because of arbitrary coding differences between the CRC implementations on different platforms, nothing very bad happened on common modern systems. On systems using the _sb8.c fallback we could segfault. Restore that check, add a new assertion and supply a test for that case. Back-patch to 12, like bae868c. Tested-by: Tom Lane <tgl@sss.pgh.pa.us> Tested-by: Alexander Lakhin <exclusion@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGLCkTT7zYjzOxuLGahBdQ%3DMcF%3Dz5ZvrjSOnW4EDhVjT-g%40mail.gmail.com
1 parent 13aeaf0 commit becfbdd
Copy full SHA for becfbdd

File tree

Expand file treeCollapse file tree

2 files changed

+24
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+24
-0
lines changed

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

Copy file name to clipboardExpand all lines: src/backend/access/transam/xlogreader.c
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,15 @@ XLogDecodeNextRecord(XLogReaderState *state, bool nonblocking)
653653
}
654654
else
655655
{
656+
/* There may be no next page if it's too small. */
657+
if (total_len < SizeOfXLogRecord)
658+
{
659+
report_invalid_record(state,
660+
"invalid record length at %X/%X: expected at least %u, got %u",
661+
LSN_FORMAT_ARGS(RecPtr),
662+
(uint32) SizeOfXLogRecord, total_len);
663+
goto err;
664+
}
656665
/* We'll validate the header once we have the next page. */
657666
gotheader = false;
658667
}
@@ -1190,6 +1199,8 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
11901199
{
11911200
pg_crc32c crc;
11921201

1202+
Assert(record->xl_tot_len >= SizeOfXLogRecord);
1203+
11931204
/* Calculate the CRC */
11941205
INIT_CRC32C(crc);
11951206
COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);

‎src/test/recovery/t/039_end_of_wal.pl

Copy file name to clipboardExpand all lines: src/test/recovery/t/039_end_of_wal.pl
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,19 @@ sub advance_to_record_splitting_zone
281281
$log_size),
282282
"xl_tot_len short");
283283

284+
# xl_tot_len in final position, not big enough to span into a new page but
285+
# also not eligible for regular record header validation
286+
emit_message($node, 0);
287+
$end_lsn = advance_to_record_splitting_zone($node);
288+
$node->stop('immediate');
289+
write_wal($node, $TLI, $end_lsn, build_record_header(1));
290+
$log_size = -s $node->logfile;
291+
$node->start;
292+
ok( $node->log_contains(
293+
"invalid record length at .*: expected at least 24, got 1", $log_size
294+
),
295+
"xl_tot_len short at end-of-page");
296+
284297
# Need more pages, but xl_prev check fails first.
285298
emit_message($node, 0);
286299
$end_lsn = advance_out_of_record_splitting_zone($node);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.