summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2023-10-15 21:43:47 +0000
committerThomas Munro2023-10-15 21:52:40 +0000
commitf1634c968101ebe48e5b7b8b274a9170669384ce (patch)
tree018339a98a91156c3c14ae621a9c9e33b61a756b
parent2759924f33a6b7021f68dda05bb34b10bb4579e2 (diff)
Acquire ControlFileLock in relevant SQL functions.
Commit dc7d70ea added functions that read the control file, but didn't acquire ControlFileLock. With unlucky timing, file systems that have weak interlocking like ext4 and ntfs could expose partially overwritten contents, and the checksum would fail. Back-patch to all supported releases. Reviewed-by: David Steele <david@pgmasters.net> Reviewed-by: Anton A. Melnikov <aamelnikov@inbox.ru> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/20221123014224.xisi44byq3cf5psi%40awork3.anarazel.de
-rw-r--r--src/backend/utils/misc/pg_controldata.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c
index 3fc8b6a8a84..b1510b0d897 100644
--- a/src/backend/utils/misc/pg_controldata.c
+++ b/src/backend/utils/misc/pg_controldata.c
@@ -23,6 +23,7 @@
#include "common/controldata_utils.h"
#include "funcapi.h"
#include "miscadmin.h"
+#include "storage/lwlock.h"
#include "utils/builtins.h"
#include "utils/pg_lsn.h"
#include "utils/timestamp.h"
@@ -53,7 +54,9 @@ pg_control_system(PG_FUNCTION_ARGS)
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -131,7 +134,9 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
tupdesc = BlessTupleDesc(tupdesc);
/* Read the control file. */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -235,7 +240,9 @@ pg_control_recovery(PG_FUNCTION_ARGS)
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));
@@ -302,7 +309,9 @@ pg_control_init(PG_FUNCTION_ARGS)
tupdesc = BlessTupleDesc(tupdesc);
/* read the control file */
+ LWLockAcquire(ControlFileLock, LW_SHARED);
ControlFile = get_controlfile(DataDir, NULL, &crc_ok);
+ LWLockRelease(ControlFileLock);
if (!crc_ok)
ereport(ERROR,
(errmsg("calculated CRC checksum does not match value stored in file")));