aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlogreader.c11
-rw-r--r--src/test/recovery/t/039_end_of_wal.pl13
2 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f2b268d2368..4ac8fc239ad 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -380,6 +380,15 @@ restart:
}
else
{
+ /* There may be no next page if it's too small. */
+ if (total_len < SizeOfXLogRecord)
+ {
+ report_invalid_record(state,
+ "invalid record length at %X/%X: wanted %u, got %u",
+ (uint32) (RecPtr >> 32), (uint32) RecPtr,
+ (uint32) SizeOfXLogRecord, total_len);
+ goto err;
+ }
/* We'll validate the header once we have the next page. */
gotheader = false;
}
@@ -795,6 +804,8 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
{
pg_crc32c crc;
+ Assert(record->xl_tot_len >= SizeOfXLogRecord);
+
/* Calculate the CRC */
INIT_CRC32C(crc);
COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
diff --git a/src/test/recovery/t/039_end_of_wal.pl b/src/test/recovery/t/039_end_of_wal.pl
index 2b00e565383..2013e663a31 100644
--- a/src/test/recovery/t/039_end_of_wal.pl
+++ b/src/test/recovery/t/039_end_of_wal.pl
@@ -287,6 +287,19 @@ ok( $node->log_contains(
$log_size),
"xl_tot_len short");
+# xl_tot_len in final position, not big enough to span into a new page but
+# also not eligible for regular record header validation
+emit_message($node, 0);
+$end_lsn = advance_to_record_splitting_zone($node);
+$node->stop('immediate');
+write_wal($node, $TLI, $end_lsn, build_record_header(1));
+$log_size = -s $node->logfile;
+$node->start;
+ok( $node->log_contains(
+ "invalid record length at .*: wanted 24, got 1", $log_size
+ ),
+ "xl_tot_len short at end-of-page");
+
# Need more pages, but xl_prev check fails first.
emit_message($node, 0);
$end_lsn = advance_out_of_record_splitting_zone($node);