Skip to content

Commit f1e0b07

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 8c2dd21 commit f1e0b07

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];
@@ -197,20 +198,30 @@ main(int argc, char *argv[])
197198
* about %c
198199
*/
199200
time_tmp = (time_t) ControlFile->time;
200-
strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
201-
localtime(&time_tmp));
201+
tm_tmp = localtime(&time_tmp);
202+
203+
if (tm_tmp != NULL)
204+
strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt, tm_tmp);
205+
else
206+
snprintf(pgctime_str, sizeof(pgctime_str), _("???"));
207+
202208
time_tmp = (time_t) ControlFile->checkPointCopy.time;
203-
strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
204-
localtime(&time_tmp));
209+
tm_tmp = localtime(&time_tmp);
210+
211+
if (tm_tmp != NULL)
212+
strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt, tm_tmp);
213+
else
214+
snprintf(ckpttime_str, sizeof(ckpttime_str), _("???"));
205215

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

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