Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ff1975d

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 627d634 commit ff1975d

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/bin/pg_controldata/pg_controldata.c

+18-7
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)