diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 946907a..5fc859d 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -31,6 +31,7 @@ #include "access/xlogrecord.h" #include "catalog/pg_control.h" #include "common/pg_lzcompress.h" +#include "common/relpath.h" #include "replication/origin.h" #ifndef FRONTEND @@ -1800,6 +1801,14 @@ DecodeXLogRecord(XLogReaderState *state, COPY_HEADER_FIELD(&fork_flags, sizeof(uint8)); blk->forknum = fork_flags & BKPBLOCK_FORK_MASK; + if (blk->forknum > MAX_FORKNUM) + { + report_invalid_record(state, + "invalid fork number %u at %X/%08X", + blk->forknum, + LSN_FORMAT_ARGS(state->ReadRecPtr)); + goto err; + } blk->flags = fork_flags; blk->has_image = ((fork_flags & BKPBLOCK_HAS_IMAGE) != 0); blk->has_data = ((fork_flags & BKPBLOCK_HAS_DATA) != 0); diff --git a/src/common/relpath.c b/src/common/relpath.c index 8fb3bed..7fdbd76 100644 --- a/src/common/relpath.c +++ b/src/common/relpath.c @@ -145,6 +145,14 @@ GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber, { RelPathStr rp; + /* + * WAL decode/display paths can reach here with unvalidated fork + * numbers; clamp as defense in depth so we never index forkNames[] + * out of bounds. Callers that can ereport should validate first. + */ + if (forkNumber < MAIN_FORKNUM || forkNumber > MAX_FORKNUM) + forkNumber = MAIN_FORKNUM; + if (spcOid == GLOBALTABLESPACE_OID) { /* Shared system relations live in {datadir}/global */