Skip to content

Commit 1b8a953

Browse files
committed
pg_controldata: Fix possible errors on corrupted pg_control
Protect against malformed timestamps. Also protect against negative WalSegSz as it triggers division by zero: ((0x100000000UL) / (WalSegSz)) can turn into zero in XLogFileName(xlogfilename, ControlFile->checkPointCopy.ThisTimeLineID, segno, WalSegSz); because if WalSegSz is -1 then by arithmetic rules in C we get 0x100000000UL / 0xFFFFFFFFFFFFFFFFUL == 0. Author: Ilyasov Ian <ianilyasov@outlook.com> Author: Anton Voloshin <a.voloshin@postgrespro.ru> Backpatch-through: 13
1 parent 8703cde commit 1b8a953

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/bin/pg_controldata/pg_controldata.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ main(int argc, char *argv[])
9797
bool crc_ok;
9898
char *DataDir = NULL;
9999
time_t time_tmp;
100+
struct tm *tm_tmp;
100101
char pgctime_str[128];
101102
char ckpttime_str[128];
102103
char mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
@@ -196,20 +197,30 @@ main(int argc, char *argv[])
196197
* about %c
197198
*/
198199
time_tmp = (time_t) ControlFile->time;
199-
strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
200-
localtime(&time_tmp));
200+
tm_tmp = localtime(&time_tmp);
201+
202+
if (tm_tmp != NULL)
203+
strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt, tm_tmp);
204+
else
205+
snprintf(pgctime_str, sizeof(pgctime_str), _("???"));
206+
201207
time_tmp = (time_t) ControlFile->checkPointCopy.time;
202-
strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
203-
localtime(&time_tmp));
208+
tm_tmp = localtime(&time_tmp);
209+
210+
if (tm_tmp != NULL)
211+
strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt, tm_tmp);
212+
else
213+
snprintf(ckpttime_str, sizeof(ckpttime_str), _("???"));
204214

205215
/*
206216
* Calculate name of the WAL file containing the latest checkpoint's REDO
207217
* start point.
208218
*
209-
* A corrupted control file could report a WAL segment size of 0, and to
210-
* guard against division by zero, we need to treat that specially.
219+
* A corrupted control file could report a WAL segment size of 0 or
220+
* negative value, and to guard against division by zero, we need to treat
221+
* that specially.
211222
*/
212-
if (WalSegSz != 0)
223+
if (WalSegSz > 0)
213224
{
214225
XLogSegNo segno;
215226

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy