Hello  hackers,

I have found an instance of a time overflow with the start time that is written 
in "postmaster.pid". On a 32-bit Linux system, if the system date is past 
01/19/2038, when you start Postgres with `pg_ctl start -D {datadir} ...`,  the 
start time will have rolled back to approximately 1900. This is an instance of 
the "2038 problem". On my system, pg_ctl will not exit if the start time has 
overflowed.

This can be fixed by casting "MyStartTime" to a long long instead of just a 
long in "src/backend/utils/init/miscinit.c". Additionally, in 
"src/bin/pg_ctl/pg_ctl.c", when we read that value from the file, we should use 
"atoll()" instead of "atol()" to ensure we are reading it as a long long.
I have verified that this fixes the start time overflow on my 32-bit arm 
system. My glibc is compiled with 64-bit time_t.
Most systems running Postgres likely aren't 32-bit, but for embedded systems, 
this is important to ensure 2038 compatibility.

This is a fairly trivial patch, and I do not currently see any issues with 
using long long. I was told on IRC that a regression test is likely not 
necessary for this patch.
I look forward to hearing any feedback. This is my first open-source 
contribution!

Thank you,


Max Johnson

Embedded Linux Engineer I

​

NovaTech, LLC

13555 W. 107th Street | Lenexa, KS 66215 ​

O: 913.451.1880

M: 913.742.4580​

novatechautomation.com<http://www.novatechautomation.com/> | 
NovaTechLinkedIn<https://www.linkedin.com/company/565017>


NovaTech Automation is Net Zero committed. 
#KeepItCool<https://www.keepitcool.earth/>

Receipt of this email implies compliance with our terms and 
conditions<https://www.novatechautomation.com/email-terms-conditions>.

From 70ec929f971577e3a78ab32d15b631954286aaf7 Mon Sep 17 00:00:00 2001
From: Max Johnson <max.john...@novatechautomation.com>
Date: Mon, 23 Sep 2024 13:41:43 -0500
Subject: [PATCH] pg_ctl and miscinit: change type of MyStartTime

The start time variable needs to be 64 bits wide on all platforms in order
to support dates past 01/19/2038. This patch fixes an overflow error on
the start time in "postmaster.pid", which can cause pg_ctl to hang.
Change the value of "MyStartTime" to long long.
Signed-off-by: Max Johnson <max.john...@novatechautomation.com>
---
 src/backend/utils/init/miscinit.c | 4 ++--
 src/bin/pg_ctl/pg_ctl.c           | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 1f0b3175ae..8669e95817 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1205,10 +1205,10 @@ CreateLockFile(const char *filename, bool amPostmaster,
 	 * both datadir and socket lockfiles; although more stuff may get added to
 	 * the datadir lockfile later.
 	 */
-	snprintf(buffer, sizeof(buffer), "%d\n%s\n%ld\n%d\n%s\n",
+	snprintf(buffer, sizeof(buffer), "%d\n%s\n%lld\n%d\n%s\n",
 			 amPostmaster ? (int) my_pid : -((int) my_pid),
 			 DataDir,
-			 (long) MyStartTime,
+			 (long long) MyStartTime,
 			 PostPortNumber,
 			 socketDir);
 
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index f9e0ee4eee..e138c5b236 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -624,7 +624,7 @@ wait_for_postmaster_start(pgpid_t pm_pid, bool do_checkpoint)
 			 * Allow 2 seconds slop for possible cross-process clock skew.
 			 */
 			pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]);
-			pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]);
+			pmstart = atoll(optlines[LOCK_FILE_LINE_START_TIME - 1]);
 			if (pmstart >= start_time - 2 &&
 #ifndef WIN32
 				pmpid == pm_pid
-- 
2.34.1

Reply via email to