Ensure that we validate the page header of the first page of a WAL file

whenever we start to read within that file.  The first page carries
extra identification information that really ought to be checked, but
as the code stood, this was only checked when we switched sequentially
into a new WAL file, or if by chance the starting checkpoint record was
within the first page.  This patch ensures that we will detect bogus
'long header' information before we start replaying the WAL sequence.
This commit is contained in:
Tom Lane 2006-04-20 04:07:38 +00:00
parent cc7eab38dd
commit eac825aa68
1 changed files with 29 additions and 2 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.236 2006/04/17 18:55:05 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.237 2006/04/20 04:07:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -2727,7 +2727,25 @@ ReadRecord(XLogRecPtr *RecPtr, int emode)
readFile = XLogFileRead(readId, readSeg, emode);
if (readFile < 0)
goto next_record_is_invalid;
readOff = (uint32) (-1); /* force read to occur below */
/*
* Whenever switching to a new WAL segment, we read the first page of
* the file and validate its header, even if that's not where the
* target record is. This is so that we can check the additional
* identification info that is present in the first page's "long"
* header.
*/
readOff = 0;
if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
{
ereport(emode,
(errcode_for_file_access(),
errmsg("could not read from log file %u, segment %u, offset %u: %m",
readId, readSeg, readOff)));
goto next_record_is_invalid;
}
if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
goto next_record_is_invalid;
}
targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / XLOG_BLCKSZ) * XLOG_BLCKSZ;
@ -3036,6 +3054,15 @@ ValidXLOGHeader(XLogPageHeader hdr, int emode)
return false;
}
}
else if (readOff == 0)
{
/* hmm, first page of file doesn't have a long header? */
ereport(emode,
(errmsg("invalid info bits %04X in log file %u, segment %u, offset %u",
hdr->xlp_info, readId, readSeg, readOff)));
return false;
}
recaddr.xlogid = readId;
recaddr.xrecoff = readSeg * XLogSegSize + readOff;
if (!XLByteEQ(hdr->xlp_pageaddr, recaddr))