Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6e4bf4e

Browse files
committed
Fix error handling of XLogReaderAllocate in case of OOM
Similarly to previous fix 9b8d478, commit 2c03216 has switched XLogReaderAllocate() to use a set of palloc calls instead of malloc, causing any callers of this function to fail with an error instead of receiving a NULL pointer in case of out-of-memory error. Fix this by using palloc_extended with MCXT_ALLOC_NO_OOM that will safely return NULL in case of an OOM. Michael Paquier, slightly modified by me.
1 parent f85155e commit 6e4bf4e

File tree

4 files changed

+39
-9
lines changed

4 files changed

+39
-9
lines changed

src/backend/access/transam/xlog.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,8 +1062,11 @@ XLogInsertRecord(XLogRecData *rdata, XLogRecPtr fpw_lsn)
10621062
if (!debug_reader)
10631063
debug_reader = XLogReaderAllocate(NULL, NULL);
10641064

1065-
if (!debug_reader ||
1066-
!DecodeXLogRecord(debug_reader, (XLogRecord *) recordBuf.data,
1065+
if (!debug_reader)
1066+
{
1067+
appendStringInfo(&buf, "error decoding record: out of memory");
1068+
}
1069+
else if (!DecodeXLogRecord(debug_reader, (XLogRecord *) recordBuf.data,
10671070
&errormsg))
10681071
{
10691072
appendStringInfo(&buf, "error decoding record: %s",

src/backend/access/transam/xlogreader.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,49 @@ report_invalid_record(XLogReaderState *state, const char *fmt,...)
5858
/*
5959
* Allocate and initialize a new XLogReader.
6060
*
61-
* The returned XLogReader is palloc'd. (In FRONTEND code, that means that
62-
* running out-of-memory causes an immediate exit(1).
61+
* Returns NULL if the xlogreader couldn't be allocated.
6362
*/
6463
XLogReaderState *
6564
XLogReaderAllocate(XLogPageReadCB pagereadfunc, void *private_data)
6665
{
6766
XLogReaderState *state;
6867

69-
state = (XLogReaderState *) palloc0(sizeof(XLogReaderState));
68+
state = (XLogReaderState *)
69+
palloc_extended(sizeof(XLogReaderState),
70+
MCXT_ALLOC_NO_OOM | MCXT_ALLOC_ZERO);
71+
if (!state)
72+
return NULL;
7073

7174
state->max_block_id = -1;
7275

7376
/*
7477
* Permanently allocate readBuf. We do it this way, rather than just
7578
* making a static array, for two reasons: (1) no need to waste the
7679
* storage in most instantiations of the backend; (2) a static char array
77-
* isn't guaranteed to have any particular alignment, whereas palloc()
78-
* will provide MAXALIGN'd storage.
80+
* isn't guaranteed to have any particular alignment, whereas
81+
* palloc_extended() will provide MAXALIGN'd storage.
7982
*/
80-
state->readBuf = (char *) palloc(XLOG_BLCKSZ);
83+
state->readBuf = (char *) palloc_extended(XLOG_BLCKSZ,
84+
MCXT_ALLOC_NO_OOM);
85+
if (!state->readBuf)
86+
{
87+
pfree(state);
88+
return NULL;
89+
}
8190

8291
state->read_page = pagereadfunc;
8392
/* system_identifier initialized to zeroes above */
8493
state->private_data = private_data;
8594
/* ReadRecPtr and EndRecPtr initialized to zeroes above */
8695
/* readSegNo, readOff, readLen, readPageTLI initialized to zeroes above */
87-
state->errormsg_buf = palloc(MAX_ERRORMSG_LEN + 1);
96+
state->errormsg_buf = palloc_extended(MAX_ERRORMSG_LEN + 1,
97+
MCXT_ALLOC_NO_OOM);
98+
if (!state->errormsg_buf)
99+
{
100+
pfree(state->readBuf);
101+
pfree(state);
102+
return NULL;
103+
}
88104
state->errormsg_buf[0] = '\0';
89105

90106
/*

src/backend/replication/logical/logical.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ StartupDecodingContext(List *output_plugin_options,
163163
ctx->slot = slot;
164164

165165
ctx->reader = XLogReaderAllocate(read_page, ctx);
166+
if (!ctx->reader)
167+
ereport(ERROR,
168+
(errcode(ERRCODE_OUT_OF_MEMORY),
169+
errmsg("out of memory")));
170+
166171
ctx->reader->private_data = ctx;
167172

168173
ctx->reorder = ReorderBufferAllocate();

src/bin/pg_rewind/parsexlog.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, TimeLineID tli,
7070
private.datadir = datadir;
7171
private.tli = tli;
7272
xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
73+
if (xlogreader == NULL)
74+
pg_fatal("out of memory");
7375

7476
do
7577
{
@@ -121,6 +123,8 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, TimeLineID tli)
121123
private.datadir = datadir;
122124
private.tli = tli;
123125
xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
126+
if (xlogreader == NULL)
127+
pg_fatal("out of memory");
124128

125129
record = XLogReadRecord(xlogreader, ptr, &errormsg);
126130
if (record == NULL)
@@ -171,6 +175,8 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, TimeLineID tli,
171175
private.datadir = datadir;
172176
private.tli = tli;
173177
xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
178+
if (xlogreader == NULL)
179+
pg_fatal("out of memory");
174180

175181
searchptr = forkptr;
176182
for (;;)

0 commit comments

Comments
 (0)