mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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
			
			
This commit is contained in:
		@@ -97,6 +97,7 @@ main(int argc, char *argv[])
 | 
			
		||||
	bool		crc_ok;
 | 
			
		||||
	char	   *DataDir = NULL;
 | 
			
		||||
	time_t		time_tmp;
 | 
			
		||||
	struct tm  *tm_tmp;
 | 
			
		||||
	char		pgctime_str[128];
 | 
			
		||||
	char		ckpttime_str[128];
 | 
			
		||||
	char		mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
 | 
			
		||||
@@ -197,20 +198,30 @@ main(int argc, char *argv[])
 | 
			
		||||
	 * about %c
 | 
			
		||||
	 */
 | 
			
		||||
	time_tmp = (time_t) ControlFile->time;
 | 
			
		||||
	strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt,
 | 
			
		||||
			 localtime(&time_tmp));
 | 
			
		||||
	tm_tmp = localtime(&time_tmp);
 | 
			
		||||
 | 
			
		||||
	if (tm_tmp != NULL)
 | 
			
		||||
		strftime(pgctime_str, sizeof(pgctime_str), strftime_fmt, tm_tmp);
 | 
			
		||||
	else
 | 
			
		||||
		snprintf(pgctime_str, sizeof(pgctime_str), _("???"));
 | 
			
		||||
 | 
			
		||||
	time_tmp = (time_t) ControlFile->checkPointCopy.time;
 | 
			
		||||
	strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt,
 | 
			
		||||
			 localtime(&time_tmp));
 | 
			
		||||
	tm_tmp = localtime(&time_tmp);
 | 
			
		||||
 | 
			
		||||
	if (tm_tmp != NULL)
 | 
			
		||||
		strftime(ckpttime_str, sizeof(ckpttime_str), strftime_fmt, tm_tmp);
 | 
			
		||||
	else
 | 
			
		||||
		snprintf(ckpttime_str, sizeof(ckpttime_str), _("???"));
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Calculate name of the WAL file containing the latest checkpoint's REDO
 | 
			
		||||
	 * start point.
 | 
			
		||||
	 *
 | 
			
		||||
	 * A corrupted control file could report a WAL segment size of 0, and to
 | 
			
		||||
	 * guard against division by zero, we need to treat that specially.
 | 
			
		||||
	 * A corrupted control file could report a WAL segment size of 0 or
 | 
			
		||||
	 * negative value, and to guard against division by zero, we need to treat
 | 
			
		||||
	 * that specially.
 | 
			
		||||
	 */
 | 
			
		||||
	if (WalSegSz != 0)
 | 
			
		||||
	if (WalSegSz > 0)
 | 
			
		||||
	{
 | 
			
		||||
		XLogSegNo	segno;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user