diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 36f5514b69e..c38ce14289f 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.39.2.1 2008/04/26 23:35:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.39.2.2 2008/05/19 18:16:46 heikki Exp $ * * NOTES * Each global transaction is associated with a global transaction @@ -56,6 +56,7 @@ #include "storage/procarray.h" #include "storage/smgr.h" #include "utils/builtins.h" +#include "utils/memutils.h" /* @@ -865,6 +866,15 @@ EndPrepare(GlobalTransaction gxact) Assert(hdr->magic == TWOPHASE_MAGIC); hdr->total_len = records.total_len + sizeof(pg_crc32); + /* + * If the file size exceeds MaxAllocSize, we won't be able to read it in + * ReadTwoPhaseFile. Check for that now, rather than fail at commit time. + */ + if (hdr->total_len > MaxAllocSize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("two-phase state file maximum length exceeded"))); + /* * Create the 2PC state file. * @@ -1045,7 +1055,9 @@ ReadTwoPhaseFile(TransactionId xid) /* * Check file length. We can determine a lower bound pretty easily. We - * set an upper bound mainly to avoid palloc() failure on a corrupt file. + * set an upper bound to avoid palloc() failure on a corrupt file, though + * we can't guarantee that we won't get an out of memory error anyway, + * even on a valid file. */ if (fstat(fd, &stat)) { @@ -1060,7 +1072,7 @@ ReadTwoPhaseFile(TransactionId xid) if (stat.st_size < (MAXALIGN(sizeof(TwoPhaseFileHeader)) + MAXALIGN(sizeof(TwoPhaseRecordOnDisk)) + sizeof(pg_crc32)) || - stat.st_size > 10000000) + stat.st_size > MaxAllocSize) { close(fd); return NULL;