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